Firebase Realtime Database をスマホで操作およびストリーミング受信する実験

PCとスマホ連携

実際に HTML 及び JavaScript でプログラミングしてみる

では、前項までを踏まえて、実際に HTML 及び JavaScript でプログラミングしてみたいと思います。
ちなみに何度も申し上げておりますが、私は HTML 及び JavaScript は素人です。
動作保証は一切いたしません。
ただ、間違えていたらコメント投稿欄等でご連絡いただけると助かります。

まず、私なりに考えた以下のスマホ用コードを作ってみました。
パソコンでも使えます。
Firebase Realtime database の読み取り及び書き換えのサンプルです。
これは、最初に紹介した動画で使ったものです。

テキストエディタで、HTML形式で保存してください
拡張子は、*.html です

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv='content-type' content='text/html; charset=UTF-8'>
    <meta name='viewport' content='width=210, initial-scale=1.3, user-scalable=yes'>
    <title>Firebase Server-Sent Events Test</title>

    <!-- by Firebase Project Overview (Use Web) -->
    <script src="https://www.gstatic.com/firebasejs/5.4.2/firebase.js"></script>
    <script>
      // Initialize Firebase
      var config = {
        apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        authDomain: "xxxxxx.firebaseapp.com",
        databaseURL: "https://xxxxxx.firebaseio.com",
        projectId: "xxxxxx",
        storageBucket: "xxxxxx.appspot.com",
        messagingSenderId: "xxxxxxxxxxxx"
      };
      firebase.initializeApp(config);
    </script>
    <!-- -------------------------------- -->

    <script type="text/javascript">
      var user_path = "test_user1";

      function signIn() {
        let mail_str = document.getElementById("mail_txt_id").value;
        let pass_str = document.getElementById("pass_txt_id").value;

        document.getElementById("firebase_status_id").textContent = "Sign In wait...";

        firebase.auth().signInWithEmailAndPassword(mail_str, pass_str).then(function() {
          document.getElementById("firebase_status_id").textContent = "Sign In Success!";
          //2秒待ってからページを再ロードすることによって、ストリーミング受信するようになる。
          setTimeout("location.reload()",2000);
        }).catch(function(error) {
          let errorCode = error.code;
          let errorMessage = error.message;
          document.getElementById("firebase_status_id").textContent = errorMessage;
          setTimeout("location.reload()",5000);
        });
      }

      //text データの読み込み
      firebase.database().ref( user_path + "/text" ).on('value', function(snapshot) {
        document.getElementById("firebase_text_id").textContent = snapshot.val();
        document.getElementById("firebase_status_id").textContent = "data received";
      });
      //color データの読み込み
      firebase.database().ref( user_path + "/color" ).on('value', function(snapshot) {
        let elements = document.getElementById("firebase_color_id");
        elements.style.backgroundColor = snapshot.val();
        elements.textContent = "color: " + snapshot.val();
      });

      //textデータの書き込み
      function writeUserTextData( t_id ) {
        let value_str = document.getElementById(t_id).value;
        firebase.database().ref( user_path ).update({ //.on の場合は子ノードも全て上書き
          text : value_str
        });
      }
      //colorデータの書き込み
      function writeUserColorData( t_id ) {
        let value_str = document.getElementById(t_id).value;
        firebase.database().ref( user_path ).update({
          color : value_str
        });
      }

      function signOut() {
        firebase.auth().signOut().then(function() {
          // Sign-out successful.
          document.getElementById("firebase_text_id").textContent = "Sign OUT";
          setTimeout("location.reload()",2000);
        }).catch(function(error) {
          document.getElementById("firebase_text_id").textContent = "Sign OUT error";
        });
      }
    </script>
  </head>

  <body style="width:210px; background-color:#000; color:#FFF">
    <FONT size='1'>
    Firebase Realtime Database Test
    <br>
    Connection Status:
    <div id="firebase_status_id" style="border-style:solid; border-width:1px; padding:2px ">
      Cannot Connection.
    </div>
    </FONT>
    <p>
      <div id="firebase_text_id" style="background-color:#225; border-style:inset; padding:5px ">
        text:???
      </div>
      text:
      <input type="text" id="text_write_id" value="Enter text"><br>
      <input type="button" value="Firebase Write" onclick="writeUserTextData('text_write_id');">
    </p>
    <p>
      <div id="firebase_color_id" style="border-style:outset; padding:5px;">
        color:???
      </div>
      <input type="button" id="black_id" value="black" onclick="writeUserColorData(this.id);">
      <input type="button" id="red_id" value="red" onclick="writeUserColorData(this.id);">
      <input type="button" id="green_id" value="green" onclick="writeUserColorData(this.id);">
      <input type="button" id="blue_id" value="blue" onclick="writeUserColorData(this.id);">
    </p>
    <p style="text-align:start; border-style:double; border-color:#FFF; padding:5px;">
      mail:<br>
      <input type="textbox" id="mail_txt_id" value=''><br>
      password:<br>
      <input type="password" id="pass_txt_id" value=''><br>
      <input type="button" value="sign in" onClick="signIn()">
      <input type="button" value="sign out" onclick="signOut();" style="background-color:#000; color:#FFF;">
    </p>
  </body>
</html>

HTML および JavaScript のプログラミング方法は、ネット上に豊富な情報がありますので、ここでは割愛させていただきます。

9~21行目の部分を、前項の「ウェブアプリに Firebase を追加」でコピーした、ご自分のコードスニペット(断片)を貼り付けて書き換えてください。
これを貼り付けることによって、ネット上の JavaScript用 Firebase アプリを読み込み、それが使用可能状態になります。

ユーザー名 test_user1 の階層は 25行目に定義しています。

これだけで、ご自分のデータベースの読み書きが可能になります。

このコードを見ると大きな疑問が湧いてくると思います。
例えば、これを HTML ファイルとして保存して、第三者ユーザーに渡す場合、ソースコードが丸見えとなります。
つまり、9~21行目のAPIキーやID部分は丸見えです
この APIキーや、messagingSenderId は隠さなければいけないものなのでしょうか?

サインイン(ログイン)はメールアドレスとパスワードで認証しているので、API キーなどは見られても問題ないものと思われますが、どうなのでしょう?
私のように趣味で使う分には、他人に公開することはないので特に問題にはなりませんが・・・。

公開したくない場合は、アクセス制限をかけた別ファイルにキーやIDを保存して、それを読み込むようなプログラムにした方が良いかもしれません。
心配な方はサポートセンターに問い合わせると良いと思います。
この件は今後の課題としたいと思います。

また、先に述べたルールの項目でアクセス制限をかけた UID はどこにも使われていないことに疑問を持ちませんか?

実は、27~43行目の関数で、サインイン認証が完了すれば、そのユーザーはUIDを持っているということになるので、UIDルールが適用されて認証されているということです。
これが理解できるようになるまで、私は数か月かかりましたよ。

これが分かると、Firebase の Authentication は、意外と簡単に実装できて、自由にアクセス制限かれられて、とても便利だなと思いますね。
前々回のこちらの記事で使った管理者権限のデータベースシークレットよりもかなり使い勝手が良いです。

サインインに成功すると、 データの取得や書き込みが可能になります。
そこで、ここでの大きなポイントは、36行目です。

サインインに成功しただけでは、データのストリーミング受信してくれません。
2秒待ってウェブページを再読み込みしています。

そうすることによって、ストリーミング受信が開始されるようになっています。
これは、Android スマホや、Windows 10 PC の Google Chrome ブラウザにはとても有効な方法です。
iOS の iPhone や iPad は後で説明していますが、うまく動く場合とそうでない場合があります。

これは私が何度も試行錯誤した結果の方法ですが、他にもっと良い方法をご存知の方は教えていただけると助かります。

Firebase のドキュメントガイドを読んで、イマイチよくわからなくても、このコードを見て、

「こうやって使えばよかったのか・・・」
とわかって頂けたら幸いです。

使い方が分かってくると、Firebase は意外とそんなに難しくないことが分かってきました。
要するに、私が Firebase ドキュメントガイドをなかなか解釈ができなかっただけでのお話でした。

作成した HTML ファイルを Windows パソコンで実行させてみる

では、まず上記で作成した HTML ファイルを Windows パソコンで実行させてみたいと思います。
最初の方で述べましたが、ブラウザは Google Chrome を起動してください
Microsoft Edge や Internet Explorer では、ストリーミング受信の EventSource / Server-Sent EventsWebSocket をサポートされていないためです。

Windows パソコンの場合は Google Chrome を既定のブラウザ設定にしていれば、ファイルをダブルクリックするだけで HTML ファイルを実行できます。

開くと下図のようになります。

これではまだ Firebase サーバーと接続できていません。
先ほど登録したユーザーのメールアドレスとパスワードを入力してサインインします。

そこで、パスワードを間違えると、下図のようにエラーメッセージが出ます。
これは Firebase の関数を使っているので、実装は簡単です。

また、メールアドレスを間違えると、下図のようなエラーメッセージが出ます。
便利ですね。

そしてサインインに成功すると、2秒後にページを再読み込みして、Firebase Realtime database サーバーからのストリーミング受信を開始します。
画面が下図のようになれば成功です。

では、Firebase ウェブページのデータを書き換えてみてください。
即、データが反映されると思います。

そして、HTMLファイルの方のテキスト入力や、color ボタンを押してみて下さい。
日本語漢字入力もOKです。
Firebase ウェブページのデータの方も即反映されていると思います。

では、次の項では、ブラウザの自動接続ストリーミングや、Androidスマホでの HTML 実行方法、および iOS での実行方法を説明してみます。

コメント

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