Firebaseを利用したログインシステムの実装

Google の BaaS である Firebase を使うと,自分でサーバ上にデータベースを構築することなく簡単に会員サイトのログインシステムが作れます.

今回は Firebase AuthenticationCloud Firestore を利用します.

Firebase Authentication

メールアドレスとパスワードによるログインシステムを簡単に作ることができます.また,電話番号を登録して SMS で認証するなど,ほかの手段も提供されています.

Cloud Firestore

Firebase で提供されている NoSQL データベースで,以前から提供されている Firebase Realtime Database をより強化したもの,みたいなイメージです.

違いを詳しく知りたい方は データベースを選択: Cloud Firestore または Realtime Database | Firebase をご覧ください.

Firestore はベータ版ですが,面白そうなので使ってみました.

Authentication と Firestore を同時に使う理由

Authentication ではメールアドレスとパスワードでログインを管理しますが,通常のサービスを考えてみるとユーザー名とパスワードでログインするケースが多いと思います.

実際メールアドレスは長くて打つのがめんどくさかったりしますし.

カスタム認証を使えばいいんじゃ?

とも思ったりしましたが,例えば誕生日とか自分のウェブサイトとか,認証に使わないようなデータをアカウント登録時に入力させたいなら,カスタム認証を使うよりも同時にデータベース使ったほうがいいと思ったんです.

実装

HTML

<script src="https://www.gstatic.com/firebasejs/4.6.0/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.6.0/firebase-firestore.js"></script>

<script src="main.js"></script>

<form name="main" action="#">
  <p>user name&amp;emsp;<input name="username" type="text" /></p>
  <p>email&amp;emsp;<input name="email" type="text" /></p>
  <p>password&amp;emsp;<input name="password" type="password" /></p>
  <input type="submit" value="submit" onclick="register()" />
</form>

最初の二行で Firebase のファイルを読み込むだけで,機能を使う準備ができます.すごいですね.

main.js に仕様を書いておいて,フォームの入力値を使って会員登録しようと思います.

JavaScript

main.js

function register() {
  var form = document.forms.main;

  var username = form.username.value;
  var email = form.email.value;
  var password = form.password.value;

  // Initialize Firebase
  var config = {
    apiKey: "API Key の値",
    authDomain: "example.firebaseapp.com",
    databaseURL: "https://example.firebaseio.com",
    projectId: "example",
    storageBucket: "example.appspot.com",
    messagingSenderId: "0123456789",
  };
  firebase.initializeApp(config);

  // Initialize Cloud Firestore through Firebase
  var db = firebase.firestore();

  // Register the user
  firebase
    .auth()
    .createUserWithEmailAndPassword(email, password)
    .catch(function (error) {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
      console.log(errorCode, errorMessage);
    });

  firebase.auth().onAuthStateChanged(function (user) {
    if (user) {
      // User is signed in.
      var displayName = user.displayName;
      var email = user.email;
      var emailVerified = user.emailVerified;
      var photoURL = user.photoURL;
      var isAnonymous = user.isAnonymous;
      var uid = user.uid;
      var providerData = user.providerData;

      console.log(uid);

      db.collection("users")
        .doc(uid)
        .set({
          username: username,
        })
        .then(function () {
          console.log("Document successfully written!");
        })
        .catch(function (error) {
          console.error("Error adding document: ", error);
        });
    } else {
      // User is signed out.
      // ...
    }
  });
}

書くことこれだけです.ドキュメント見れば簡単に書けると思います.

フォームの値がうまく取得できず,寧ろそっちのほうが苦労してしまいました....

最後に

一部持論を展開していますが,素人なので間違いなどあれば教えてください.