Realtime database のルールで、ユーザー UID アクセス制限を作成
では、先ほど作ったユーザーのみが Realtime database の読み書き可能なようにアクセス制限をかけてみます。
まず、下図のように「 Database 」の「ルール」を開き、以下のようなルールを入力してください。
xxx… のところを、2か所とも先ほどコピーした UID を貼り付け書き替えてください。
カンマの位置やクォーテーション、ダブルクォーテーションの位置に気をつけてください 。
{ "rules": { ".read": "auth.uid === 'xxxxxxxxxxxxxxx'", ".write": "auth.uid === 'xxxxxxxxxxxxxxx'" } }
すべてよければ「公開」をクリックします。
これで、Realtime database の読み書きは、先ほど作ったユーザーのみの権限になりました。
ただし、この場合、そのユーザーが全ての階層ツリーを読み書きできてしまいます。
今回の場合、test_user1 階層内だけ、そのユーザーアクセスにしたいですよね。
その場合、以下の様なルールにします。
{ "rules": { "test_user1": { ".read": "auth.uid === 'xxxxxxxxxxxxxxxxxxxx'", ".write": "auth.uid === 'xxxxxxxxxxxxxxxxxxxx'" } } }
こうすれば、先ほど作成したユーザーがアクセスできるのは、test_user1内のデータのみとなり、より安全です。
これを理解するのに、私はとても苦労しました。
Firebase ドキュメントの Realtime database のウェブ用ガイドを読み解いてみる
ちょっと回りくどいかもしれませんが、ここでは私のちょっとした苦労話が入っています。
既に理解している方は読み飛ばしてください 。
Firebase の日本語ドキュメントガイドがありますが、正直言って JavaScript アマチュアの私には難解でした。
そこで、 ウェブ用ガイドを私なりに読み解いてみたので、ザッと説明してみます 。
具体的なプログラミングは後の項で説明します。
Realtime database のデータを取得する HTML 及び JavaScript ファイルを作成するには、以下の Firebaseドキュメントを参照する必要があります。
ウェブアプリに Firebase を追加とは
これは 、 以下のリンクの Firebase キュメントガイドにあります 。
https://firebase.google.com/docs/web/setup?hl=ja
ただ、最初これを読んだ時、素人アマチュアの私はサッパリ分かりませんでした。
ウェブ検索しても全くわかりませんでした。
でも、要するにこれは、コードの断片(スニペット)をコピペするだけのことだったのです。
まず、下図のように「 Project Overview 」をクリックして、 Web アプリのアイコン「</>」をクリックします。
すると下図のような画面が出てくるので、「コピー」をクリックするとクリップボードにコピーされます。
このコードを、 Web ページ作成用の HTML ヘッダに貼り付けるだけのことだったのです。
このコードを貼り付ければ、ウェブページで Firebase を使うことが可能になります。
結果的に、意外と簡単でした。
具体的なプログラミング方法は後で説明します。
メールアドレスとパスワードを使用してユーザーのサインイン(ログイン)を行う JavaScript 関数について
上記のように、 Web ページで Firebase が使えるようになっても、先ほどデータベースのルールを作成したので、認証できないと Realtime database を読み書きできません。
前々回のこちらの記事では、ESP32 や M5Stack などの WiFi マイコンで管理者権限キーを使いましたが、ここでは、先ほど作成したメールアドレスとパスワードによるユーザー認証方法を使います。
データベースシークレットよりも細かいアクセス設定が可能です。
本当は、Google のアカウントで既にサインイン(ログイン)してあれば、そのまま認証してFirebase realtime database にアクセスできるという方法があり、そちらの方がよりセキュリティが高いです。
それは、OAuth 2.0 というものですが、これは私自身にはとっても難しく、まだ実現できておりません。
いつかそれができるようになったらこのブログで紹介したいと思います。
では、メールアドレスとパスワードによる JavaScript ユーザー認証方法を説明します。
それは Firebase の以下のドキュメントにあります。
https://firebase.google.com/docs/auth/web/password-auth?hl=ja
これによると、サインインする JavaScript コードは以下になります。
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // ... });
email と password のところに、先ほどユーザー登録したメールアドレスとパスワードが代入できれば認証できるわけです。
この関数でサインインできれば、後で紹介する読み取りと書き込みコードが実行可能になります。
これの実際の使い方は、後ほど紹介します。
Realtime database からデータを取得(読み取り)する JavaScript 関数について
Firebase Realtime database から JavaScript でデータを取得(読み取り)する方法は、Firebase の以下のドキュメントにあります。
https://firebase.google.com/docs/database/web/read-and-write?hl=ja
これによると、以下の関数を使えば、データベースに変更があった時だけイベントが発生して、データを取得(読み取る)ことができるとのことです 。
var starCountRef = firebase.database().ref('posts/' + postId + '/starCount'); starCountRef.on('value', function(snapshot) { updateStarCount(postElement, snapshot.val()); });
これには、posts/ や postId とか、見慣れないものがあります。
ここのところが私のようなアマチュア素人が戸惑ってハマるところです。
posts/ や postId って、どこで設定するの???
これ、ほんとよく分からなくて、かなり悩みました。
結局、意外と簡単で、要するにデータベースのただの階層ツリーの単なる一例ということだったのです。
先ほど作った私のデータベースで、color の値を取得したいとすれば、
.ref(‘test_user1/color’);
という感じで、フォルダpath形式のような文字列を代入するだけのことだったのです。
これを理解するまでに、私は数ヶ月かかりました。
この関数は、サインインで認証されたら読取可能になります。
これの実際の使い方は後ほど紹介します。
Realtime database にデータを書き込みする JavaScript 関数について
これは、Firebase の以下のドキュメントにあります。
データ読み取りと同じところにあります。
https://firebase.google.com/docs/database/web/read-and-write?hl=ja
これも読み取りと同じように、メールアドレスとパスワードで認証後に書き込むことが可能になります。
データを書き込むための関数は、例として以下のように掲載されています。
function writeUserData(userId, name, email, imageUrl) { firebase.database().ref('users/' + userId).set({ username: name, email: email, profile_picture : imageUrl }); }
set() を使えば、データ書き込みできますが、子ノード(子階層)まで全て書き換えてしまいます。
ターゲットのデータだけ書き換えたい場合、update() を使います。
すると、
function writeUserData(userId, name, email, imageUrl) { firebase.database().ref('users/' + userId).update({ username: name, email: email, profile_picture : imageUrl }); }
となります。
writeUserData(userId, name, email, imageUrl)
という関数は、任意の自作関数で、userId, name, email, imageUrl は任意の引数です。
ですから、email 以外、Firebase コンソールにそれらを登録するようなところはありません。
少なくとも、私はしばらく勘違いしていました。
どこで user ID を登録するんだろうと、延々と悩んでいました。
また、ここの email は、先ほど作成したユーザーの email とはあまり関係ないと思った方が良いです。
サインイン(ログイン)したユーザーの email を取得する関数があり、それを代入するという方法がありますが、最初それを考えてしまうとややこしくなります。
ここもまた、アマチュアの私がハマるところでもありました。
また、
(‘/users/’ + userId)
というところがあると思います。
これは要するに、Realtime database で users という階層の下に、UID文字列の階層が作られていて、単なるそれのパスということです。
私は勘違いしていたのですが、UID認証をしているわけではありません。
これは、どういう場面で使うのかというと、同じ階層で、異なる UID でアクセスできるようにしたい場合です。
例えば、test_user1 という同じ階層で、異なる UID 階層を作成すると、下図の様になります。
ただ単に、UID 文字列で作った階層名というだけのお話です。
ルールは、これ用に新たに作成しなければなりませんが、ここでは割愛します。
こういう例はあまり使わないと思うので、深く考えずに先に進んだ方が良いです。
分かってしまえば実に簡単で拍子抜けしてしまいましたが、専門分野のマニュアルって、アマチュアの私にはとにかく難解でした。
この説明でもイマイチ良く分からないかも知れません。
逆に混乱してしまうかも知れませんね。
とりあえず、先に進んで、実際にプログラミングして動かしてみるとだんだん分かって来ると思います。
では、次では実際に HTML 及び JavaScript を組んで、Realtime database の読み書きをやってみます。
コメント