Firebase Realtime Database のデータ保存、取得、ストリーミング受信実験( ESP32 , M5Stack )

M5Stack

4.Realtime Database の作成

次に、Firebase の Realtime Database を作成します。

下図の様に、「Database」をクリックします。

すると、下図の様な画面になります。
Cloud Firestore というのは、Realtime Database の進化したものですが、まだベータ版なので今回は使いません。
下図の様に、下の方にスクロールします。

すると、従来の Realtime Database の「データベースを作成」をクリックします。

すると、下図の画面が出るので、「テストモードで開始」を選択し、「有効にする」をクリックします。

すると、下図の様な画面になります。
現在まだデータベースが作られていないので、「+」のところをクリックします。

すると、下図の様に、「名前」欄と「値」欄が出るので、何でも良いので入力します。
データベースは1つ以上作って置かないと、データベースは作成されていない状態になってしまうので、何か適当に入力します。
「値」欄に入力する場合、数値はそのまま半角で入力すれば良いのですが、文字の場合は半角ダブルクォーテーションで囲います。
例:

“赤色”

入力し終わったら、下図の様に「追加」をクリックします。

すると、下図の様な画面になります。

これで、とりあえず test という名前に値が 0 という数値のデータベースが作成されました。
値をダブルクォーテーションで囲って入力すれば文字列にすることもできます。
日本語も入力できます。(UTF-8コード)

ただ、赤字のメッセージのように、このままだと世界中の誰でもデータベースの書き換えおよび読み取りが可能な状態で、ちょっと危険です。
よって、次の項でアクセス制限をかけます。

5.Realtime Database にルールを設定して、アクセス制限をかける

では、これのアクセス制限はどうなっているかというと、下図の様に「ルール」をクリックします。

このように、読み取りと書き込みが ”true” になっているので、だれでも書き替え読み取り可能状態です。

スマホや外部のパソコンなどからアクセスした時に、最低限のアクセス制限をかける設定は以下です。

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

これは、auth認証でログインしたユーザーだけが読み取りおよび書き換え可能です。
でも、ログインしたユーザーならばルートのデータベースも自由に作成されてしまいます。

私の場合は M5Stack や他の ESP32 デバイス、そしてスマホなどの複数のデバイスを接続して使いたいので、他のデバイスが接続されたときにルートにデータを作成されては困ります。

その場合、一つ階層をプラスして、例えば test_user1 というものを作成したルールを作成します。
要するに、Firebase Realtime Database のウェブドキュメントにあるような、USER を作るようなものです。

実は、私は、最初ドキュメントを読んで、ユーザー名ってどこで作成して登録するのだろうと、いろいろ調べたのですが、どこにも説明されていなくて悩みました。

でも、実際はただ単に「user」という階層ツリーを作るだけだったのです。
名前は何でも良かったのです。
ドキュメントには「USERS」とか「user/」とか、いろいろあって、ほんとに悩みました。
アマチュアがFirebase 始める時に、ハマるポイントかも知れません。

ということで、例として、データベースにtest_user1 という名前の階層を作り、その階層のルールを以下の様に設定してアクセス制限をかけます。

{
  "rules": {
    "test_user1": {
      ".write": "auth != null",
      ".read": "auth != null"
    }
  }
}

そうしたら、「公開」をクリックします。

すると、赤いメッセージは消えると思います。

では、このルールに沿うように、データの方も「test_user1」という階層ツリーを作成していきます。

その前に、先ほど作ったtestというデータベースを削除しちゃいます。
下図の様に「×」印をクリックします。

すると、下図の画面になるので、「削除」をクリックするとtestという階層データは消えて、データベースが空になります。

そうしたら、再び下図の様に「+」をクリックします。

次に、下図の様に名前欄に test_user1 を入力したら、値欄には何も入力せずに、「+」印をクリックします。

とりあえず、ここでは下図の様に、名前欄に text、値欄に hello world と入力してEnter 又は「追加」をクリックします。

同じように、test_user1 の階層に別のデータを入力する場合、下図の様に「+」印をクリックします。

そして、例として、下図の様に color: red というデータを作って置きます。

これで、test_user1 という階層に、color と text という名前データが作成されました。

このtest_user1 という階層が、先ほど作ったルールが適用されるわけです。
つまり、test_user1内のデータは、Authentication ( auth )認証でログインしたユーザーのみ、読み取りおよび書き換えが可能です。

そして、これの優れているところは、ルート階層やtest_user1 以外の階層には読み取りや書き換えできないとこうところです。

ただし、管理者権限ならば、どこでも読み取り、書き換え可能です。
管理者権限とはパソコンでFirebase にログインしたユーザーと、アクセストークンや従来のデータベースシークレットを取得したユーザーです。
これについては後で述べます。

ここで注意して欲しいのは、このルールの場合、test_user1 という名前が分かってしまえば、ログインした別のユーザーは test_user1 の内容を読み書き出来てしまうという欠点があります。

それの対策として、ユーザー UID というものを使ってルールを作ります。
この UID の作り方は今回は見送り、次回の記事で説明しますが、ここでは UID を作ったものとして、以下のようなルールにします。

{
  "rules": {
    "test_user1": {
        ".read": "auth.uid === 'xxxxxxxxxxxxxxxxxxxxxxx'",
        ".write": "auth.uid === ' xxxxxxxxxxxxxxxxxxxxxxx '"
    }
  }
}

こうすれば、他のユーザーによってtest_user1 のデータの読み書きができなくなり、より安全です。

後で詳細を説明しますが、この uid というものは、スマホなどのブラウザからメールとパスワードでログインすれば、uid というものは自動的に照合されるシステムになっています。
それは JavaScript等で作ったシステムによるもので、M5Stack や ESP32 などのマイコンデバイスからデータを操作する場合はデータベースシークレットを使った管理者権限でログインするため、uid は不要です。

この辺が初めて使う方はちょっと戸惑うところだと思います。

これでアクセス制限ができたので、次へ進みます。

コメント

  1. Yosuke より:

    突然のコメントにて失礼します。
    Firebase Realtime Databaseの内容でもないので申し訳ないのですが、
    ESP32でキーマトリクス回路を作りたいと思い、
    ESP32DEVkitCに74HC138のデマルチプレクサをつないで
    作ったのですが、ちとうまくいかないところがありまして、
    もしESP32でデマルチプレクサかマルチプレクサを使われた経験が
    ございましたら、伺いたいことがございます。
    いかがでしょうか。
    ※Arduinoではうまくいったキーマトリクス回路を
    そのままESP32に流用しようとしています。

  2. Yosuke より:

    mgo-tecさん

    ご返信いただきまして誠ありがとうございます。
    リンクして頂いたページを中心に、
    SPI通信を勉強してみようと思います。

    すみませんが、もう1点伺いたいことがございます。
    Arduino(ATmega328p)に74HC138をつなげば、
    キーマトリクス回路を正常に組めています。
    そこで、ESP32と74HC138の間にATmega328pを噛ませて、
    ESP32 – ATmega328p – 74HC138 – ボタン達のようにつなぎ、
    ESP32とATmega328pで何らかの通信をする方法を
    素人考えで考えてみたのですが、
    SPI通信などを利用して、ATmega328pからESP32に値を送る
    ようなことは可能でしょうか?

    お忙しいところ恐れ入りますが、何かご存知でしたら、
    ご返信いただければ助かります。

    • mgo-tec mgo-tec より:

      Yosukeさん

      多分、ESP32 と Arduino で SPI データ通信は可能だと思いますが、そのデバイス間ではシリアル通信しかやったことがありませんので、アドバイスできません。
      私が個人的に思うには、Arduino を噛ませないでも、ESP32 だけで十分可能ではないかと思います。
      ESP32 のクロックの方が高速ですし・・・。
      ということで、あまりお役に立てず、申し訳ございません。

  3. Yosuke より:

    mgo-tecさん

    ご返信頂きましてありがとうございます。
    EPS32にマルチプレクサやデマルチプレクサをつなぎますと、
    押していないボタンが押されたような反応になってしまう等、
    笑ってしまうほど意図しない挙動になってしまい、
    Arduinoで出来ていたことがこんなにできないのかと困っておりました。
    ただ、やはり安価にBluetooth通信が出来るの機能は捨てがたいので、
    アドバイス頂いた通り、EPS32のみでもう少し試行錯誤を
    続けてみようと思います。

    EPS32ユーザーの方とお話できただけでも嬉しかったです。
    本当にありがとうございました。

  4. さっさ より:

    質問です!!
    M5Stackを使っています。
    Wi-Fi、サーバーとの接続共に良好ですが、「400 Bad request」が返ってきてしまいます。
    これってfirebaseのデータベースのシークレットが既に廃止されてるからなんでしょうか?
    Firebase Admin SDKを使用しないといけませんか?

    • mgo-tec mgo-tec より:

      さっさ さん
      記事をご覧いただき、ありがとうございます。

      今、直ぐに検証できない状態ですので、もう少々お待ちくださいませ・・・。

      • さっさ より:

        返信ありがとうございます。
        いつも参考にしています。
        めちゃめちゃ助かってます!

        • mgo-tec mgo-tec より:

          さっさ さん

          お待たせしました。
          当方のM5Stackで確認したところ、特に問題有りませんでした。

          久々にFirebaseコンソールを開きましたが、従来のデータベースシークレットはまだ存在しています。
          赤文字で「データベースのシークレットは廃止された」と表示されておりますが、「レガシーの Firebase トークン生成ツールを使用する」と表示されているので、問題ありません。

          因みに、このページの7項目

          7.ブラウザのURL 入力欄にURL を入力して、Realtime Database の値を取得してみる

          を参照して、ブラウザのURL欄にデータベースシークレット入りのURLを入力してみてください。
          エラーが出ていなければ、問題無く使用できるはずです。

          あと、気になったのは、Arduinoスケッチのhostのところのアドレスには「https://」は不要ですのでご注意ください。
          以上、再度確認してみてくださいませ。

  5. ESP32 より:

    突然のコメントにて失礼します。
    4ページ目のソースコード39行目の前に
    client.setInsecure();
    が必要だと思われます。これを付け足すことで、DBに接続することができました。

    • mgo-tec mgo-tec より:

      ESP32さん

      ご指摘、ありがとうございます。
      この記事は3年以上前に書いたもので、いろいろと変わってしまったようですね。
      確かに当方で試した結果、ルート証明書が無いためにアクセスしてくれませんでした。
      Arduino core ESP32 のバージョンは2.0.2 です。
      おっしゃる通り、client.setInsecure(); を足せばアクセスできました。
      いつの間にかこんな関数ができていたんですね。
      教えて頂き、ありがとうございます。

      早速、ソースコードも修正しました。
      ただ、5ページ目のPATCHを使うコードはまだ動かないので、検証中です。
      できたらまたこのコメント欄でご報告します。

  6. ESP32 より:

    以前、指摘をさせていたいただいた者です。修正ありがとうございます。
    質問です。Firebase Realtime Databaseで読み込みしながら、書き込みをしたいです。ソースコードを教えていただけないでしょうか。
    「client.stop(); //これ絶対必要」をデータベースに書き込み終わったときに実行してしまうと、読み込みが途切れてしまい、データベースのデータが変わっても、変わったのがわからなくなってしまいます。(わかりにくい文章ですみません。)
    お忙しいところ恐れ入りますが、ご返信いただければ助かります。

    • mgo-tec mgo-tec より:

      ESP32さん

      PATCHリクエストの連続書き込みがようやくできました。5ページ目のコードを修正しました。
      また、そのついでにご要望にお応えして、データの送信とEventストリーム受信の両方を行うスケッチを書いてみました。
      Arduino core ESP32 のバージョンが2.0.2になると、だいぶ仕様が変わっていましたね。
      PATChリクエストはclient.stopしてしまうと、clientインスタンスを開放しないと再接続してくれなかったので、関数内でインスタンス生成する方式に変え、Eventストリーム受信のclientインスタンスは別で生成しました。
      以下のリンクにコードを載せておきます。
      https://www.mgo-tec.com/blog-entry-firebase-realtime-database-sever-sent-events-esp32-m5stack.html/5#title12

      • ESP32 より:

        教えていただきありがとうございます。
        読み込みと書き込み同時にできました!
        来年の夏休みの工作に活用していきたいです。

タイトルとURLをコピーしました