開発環境:Mac
firebase:6.5.0
firebaseとjavascriptを使ったチャットアプリでgoogle認証を追加したいです。
下記のリンク先の動画を参考に、FirebaseでGoogle認証を導入したいのですが、
Youtube
ログインボタンを押して実行すると下記のようなエラーが出ます。
main.js:48 Uncaught ReferenceError: base_provider is not defined
at HTMLButtonElement.<anonymous> (main.js:48)
わからない点が2点あり、
・jsの48行目で定義しているのに、not definedとなっている点
・HTMLの最後のあたりでも何か起こっているらしいのですが、google認証のコードを追加するまではこのjsで動いていたので読み込みが失敗しているということではないかなと思ってい、HTMLの何がおかしいのか
です。
どなたかご教授いただければ幸いです。
コードは以下の通りです。
HTML
1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <link rel="stylesheet" href="styles.css"> 7 <title>chat</title> 8</head> 9 10<body> 11 <h1> 12 <button id="login" class="login">Login</button> 13 <!-- ログインしてない時はログアウトボタンは非表示 --> 14 <button id="logout" class="hidden logout">Logout</button> 15 </h1> 16 <ul id="messages" class="hidden wrapper"></ul> 17 <!-- formなので、送信ボタンがなくてもreturnで送信できる --> 18 <!-- フォームに入力する時に、入力候補が出てくると見にくいので消す --> 19 <form autocomplete="off" class="hidden"> 20 <input type="text" id="message" placeholder="your message..." class="msg"> 21 </form> 22 23 <!-- <script src="https://www.gstatic.com/firebasejs/6.5.0/firebase-app.js"></script> --> 24 <!-- 機能別のスクリプトになる --> 25 <script src="https://www.gstatic.com/firebasejs/6.5.0/firebase-app.js"></script> 26 <scrip> 27 <script src="https://www.gstatic.com/firebasejs/6.5.0/firebase-firestore.js"></script> 28 <script src="https://www.gstatic.com/firebasejs/6.5.0/firebase-auth.js"></script> 29 <script src="main.js"></script> 30</body> 31 32</html> 33
CSS
1body{ 2 font-size:14px; 3 font-family: 4 Verdana, Geneva, Tahoma, sans-serif; 5 padding:20px; 6 7} 8h1{ 9 font-size:22px; 10 font-weight:normal; 11} 12 13li{ 14 line-height:2; 15 list-style: none; 16 margin:15px; 17 18} 19input[type="text"]{ 20 padding:6px 8px; 21 font-size:14px; 22 width:300px; 23} 24 25h1 > button { 26 float:right; 27} 28 29.hidden{ 30 display: none; 31} 32 33.wrapper{ 34 min-height: 100vh; 35 position: relative;/*←相対位置*/ 36 padding-bottom: 120px;/*←footerの高さ*/ 37 box-sizing: border-box;/*←全て含めてmin-height:100vhに*/ 38} 39 40.login{ 41padding:30px 60px; 42text-align: center; 43 44} 45 46 47.logout{ 48 position: fixed; /* 要素の位置を固定する */ 49 top: 0; /* 基準の位置を画面の一番下に指定する */ 50 right:0; 51 margin:30px 30px; 52} 53 54.msg{ 55 position: fixed; /* 要素の位置を固定する */ 56 bottom: 0; /* 基準の位置を画面の一番下に指定する */ 57 width: 300px; /* 幅を指定する */ 58 border: 3px solid #a9a9a9; /* ボーダーを指定する */ 59}
JavaScript
1// 変数のスコープを限定する 2// 全体を即時関数で囲っておく 3 4(() => { 5 6 'use strict'; 7 const firebaseConfig = { 8 apiKey: "AIzaSyBYhs5TXHHPIu24MqupS4XsXUG3ovyPgh0", 9 authDomain: "chat-98ce8.firebaseapp.com", 10 databaseURL: "https://chat-98ce8.firebaseio.com", 11 projectId: "chat-98ce8", 12 storageBucket: "chat-98ce8.appspot.com", 13 messagingSenderId: "456970089843", 14 appId: "1:456970089843:web:05f584754bb617de" 15 }; 16 17 18 // Initialize Firebase 19 firebase.initializeApp(firebaseConfig); 20 21 22 const db = firebase.firestore(); 23 // messagesというcollectionが使えるように 24 const collection = db.collection('messages'); 25 // authのインスタンスを作って使えるように 26 const auth = firebase.auth(); 27 // ユーザーの情報を保持する変数の宣言 28 // nullで初期化しとく 29 let me = null; 30 31 // messageの要素を取得する(idをふったので) 32 const message = document.getElementById('message'); 33 // formにはqueryセレクタを使えばOK 34 const form = document.querySelector('form'); 35 36 // 要素を取得! 37 const messages = document.getElementById('messages'); 38 39 // ログインとログアウトボタンを取得 40 const login = document.getElementById('login'); 41 const logout = document.getElementById('logout'); 42 43 44 45 // クリックイベントの設定 46 // googleでのログイン認証 47 login.addEventListener('click', () => { 48 base_provider = new firebase.auth.GoogleAuthProvider() 49 firebase.auth().signInWithPopup(base_provider).then(function (result) { 50 console.log(result) 51 console.log("Success...Google Account Linked") 52 }).catch(function (err) { 53 console.log(err) 54 console.log("Failed to do") 55 }) 56 }); 57 58 // logout.addEventListener('click', () => { 59 // auth.signOut(); 60 // }); 61 // ログイン状態の監視 62 auth.onAuthStateChanged(user => { 63 if (user) { 64 // ログインした時にuserをセットしてあげる 65 me = user; 66 67 // ここで何も書かないと、messageがある状態でlogoutすると 68 // 再ログインした時に、同じmessageがappendChildされるので、一旦messa meの内容を 69 // クリアにする必要がある 70 // messagesの最初の子要素が存在する限りmessagesからmessagesの最初の子要素を削除していく 71 while (messages.firstChild) { 72 messages.removeChild(messages.firstChild); 73 } 74 75 // ==もしuserがtrueだったらログインしていることになるので、collectionの監視をこのなかに入れる=== 76 // 格納したデータを表示 77 // 「処理が成功したら」のthen 78 // snapshotが返ってくるので、それをループで処理 79 // collectionをgetしただけだとドキュメントに振られたIDの順番になる 80 // get()の前でorderBy()として、createdでソートする 81 // collectionの値の変更を監視して、違うユーザーが投稿した時も、読み込みなしで更新されるようにonSnapshotをかく 82 collection.orderBy('created').onSnapshot(snapshot => { 83 // 返ってきたデータをdocとする 84 snapshot.docChanges().forEach(change => { 85 // データが追加された時だけ、この処理をしたい 86 if (change.type === 'added') { 87 // そのデータで、li要素を作る 88 const li = document.createElement('li'); 89 // 一覧でも、投稿者がわかるようにする 90 // 受け取る内容をchangeとして 91 // データをdで受け取る 92 const d = change.doc.data(); 93 // uidが長いので最初の8けただけにする 94 li.textContent = d.uid.substr(0, 8) + ':' + d.message; 95 // messagesに対して、子要素としてliを追加していく 96 messages.appendChild(li); 97 } 98 }); 99 // ログアウトすると読み込み権限がなくなるので、onSnapshotでの処理に失敗する 100 // 失敗した時の処理を指定するには、第2引数にエラーが出た時の処理を渡す 101 // 特に何もしたくないので{}内に書かない 102 }, error => { }); 103 console.log(`Logged in as: ${user.uid}`); 104 // ログインに成功したらloginボタンは消す=hiddenクラスをつける 105 // logoutもformもmessageもhiddenクラスを外したいのでfoeEachで処理 106 login.classList.add('hidden'); 107 // それぞれの要素をelementで受け取る 108 [logout, form, messages].forEach(el => { 109 // elementのclassListからclassListをremoveすればOK 110 el.classList.remove('hidden'); 111 }); 112 message.focus(); 113 return; 114 } 115 // ログアウトした時にはnullに戻す 116 me = null; 117 console.log('Nobody is logged in'); 118 login.classList.remove('hidden'); 119 [logout, form, messages].forEach(el => { 120 el.classList.add('hidden'); 121 }); 122 }); 123 124 125 // formにsubmitイベントを設定する 126 form.addEventListener('submit', e => { 127 // ページ遷移しないように 128 e.preventDefault(); 129 130 // 空文字は投稿できないようにtrimを使う 131 // returnで処理を抜ける(?) 132 const val = message.value.trim(); 133 if (val === "") { 134 return; 135 } 136 137 138 // messageを空にしつつ、focusを当てると親切 139 // ここの処理を上に持っていくともたつかない 140 message.value = ''; 141 142 143 // ⬇︎保存の処理 144 // collectionに対して、addとすると、ドキュメントにユニークなidをつけてくれる 145 collection.add({ 146 // messageがキーで、testという文字列を書き込んでみる 147 // 追加する値に関しては、messageのvalueを使えばOK 148 message: val, 149 // 保存するデータにcreatedキーでサーバー側のタイムスタンプを取得して設定する 150 created: firebase.firestore.FieldValue.serverTimestamp(), 151 // meはnullになり得るので、一応条件演算子を使ってnullの時はnobodyになるように 152 uid: me ? me.uid : 'nobody' 153 }) 154 // thenで処理が成功した時の処理 155 // docを引数にしつつidを表示したい 156 // バッククオートを使えば、値の埋め込みができる 157 .then(doc => { 158 console.log(`${doc.id}added!`); 159 160 }) 161 // エラーが起きた時の処理はcatchでかける 162 // ので、エラーの内容を表示させる 163 .catch(error => { 164 // 書き込めなかった時のエラーを追加 165 console.log('document add error!'); 166 console.log(error); 167 }); 168 }); 169 // focusを当てる処理は、ページが読み込まれる時にも行う 170 message.focus(); 171 172})();
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/17 14:16