アルパカログ

Webエンジニア兼マネージャーがプログラミングやマネジメント、読んだ本のまとめを中心に書いてます。

React FirebaseでGoogleログインを実装する方法(Authentication)

f:id:otoyo0122:20200917130325p:plain:w300

ReactアプリにGoogleログインを実装したいときは、Firebase AuthenticationとFirebase SDKを使うと簡単です。

むしろ、Firebase AuthenticationやGCPコンソールでのOAuthクライアントの設定の方でハマりがちかもしれません。

このエントリでは、ReactアプリにGoogleログインを実装する際の方法を、トラブルシューティングと共に紹介します。

Firebase AuthenticationでGoogleログインの有効化

Firebase Authenticationでは、ユーザーに提供するログイン方法を選ぶことができます。

Firebaseコンソール > Authentication > Sign-in method > Google > 鉛筆アイコン > 「有効にする」から有効にします(下記画像)。

f:id:otoyo0122:20200913205157p:plain:w600

Firebaseの設定ファイル作成

設定を書いておくためにFirebase.jsを作成します。

設定内容は、Firebaseコンソール > 歯車アイコン > プロジェクトを設定 > マイアプリ > Firebase SDK snippet > 構成のチェックボタンをオンにすることで表示されます。

もしまだアプリを追加していない場合は、アプリを追加 > Webアプリから、事前にアプリを追加してください。

f:id:otoyo0122:20200917124747p:plain:w600

Firebase.jsは下記のようになります。

import firebase from 'firebase/app';
import "firebase/auth";

const firebaseConfig = { // 構成そのまま
  apiKey: "...",
  authDomain: "...",
  databaseURL: "...",
  projectId: "...",
  storageBucket: "...",
  messagingSenderId: "...",
  appId: "...",
  measurementId: "..."
};

firebase.initializeApp(firebaseConfig);
export default firebase;
export const db = firebase.firestore();

ログインボタンを表示する

App.jsにログインボタンと、ログインハンドラを追加します。

import React, { Component } from 'react';
import firebase, { db } from '../Firebase';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = { userId: null };

    this.login = this.login.bind(this);
  }

  login() {
    const provider = new firebase.auth.GoogleAuthProvider();

    firebase.auth().signInWithPopup(provider)
      .then(function(result) {
        console.log("logged-in user.uid: ", result.user.uid);
        this.setState({ userId: result.user.uid });
      })
      .catch(function(error) {
        console.log(error);
      });
  }

  render() {
    let loginButton;
    if (this.state.userId) {
      loginButton = <button onClick={this.login}>log-in</button>;
    }

    return (
      <div className="App">
        {loginButton}
      </div>
    );
  }
}

export default App;

npm startでサーバーを起動して動作確認します。ログインボタンが表示されているはずです。

ログインするとログインボタンが非表示になります。実際にはログイン後のページを表示すると良いでしょう。

ログイン状態を永続化する

ページを開くたびに毎回ログインを求められるのはユーザー体験が良くないです。そこで、ログイン状態を永続化します。

そのためには、ログイン状態の永続化の設定と、ログイン状態の確認が必要です。

まず、ログイン状態の永続化設定を行います。login()メソッドの中身を下記のようにsetPersistence()のコールバックへ移動します。

setPersistence()では永続性のタイプを指定できます。詳しくは下記ページをご覧ください。

login() {
  firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)
    .then(function() {
      const provider = new firebase.auth.GoogleAuthProvider();

      firebase.auth().signInWithPopup(provider)
        .then(function(result) {
          this.setState({ userId: result.user.uid });
        }.bind(this))
        .catch(function(error) {
          console.log("Google sign-in error: ", error);
        });
    }.bind(this));
}

次に、ログイン状態を確認し、ログインしていたらstate.userIdをセットします。

ログイン状態を確認するには、ログイン状態の変更をonAuthStateChanged()で監視します。ログインしているとコールバック関数にログインユーザーが渡されます。

ログイン状態の監視を下記のようにcomponentDidMount()に追加します。

componentDidMount() {
  firebase.auth().onAuthStateChanged(function(user) {
    let userId = null;
    if (user) {
      userId = user.uid;
    }

    this.setState({ userId: userId });
  }.bind(this));
}

これで、ログイン状態が永続化され、毎回ログインする必要がなくなりました。

ログアウト

ログアウトはsignOut()メソッドを呼ぶだけです。

firebase.auth().signOut();

トラブルシューティング

ブラウザのコンソールに下記のようなエラーメッセージが表示され、うまく動かないことがあります。

  • エラー400: redirect_uri_mismatch

これは、Google認証後のリダイレクトURLがGCPコンソールに登録されていない場合に起こります。エラー画面に表示されている https://<project-id>.firebaseapp.com/__/auth/handler のようなURLを登録します。

GCPコンソール > APIとサービス > 認証情報 > OAuth 2.0 クライアント ID > 該当のIDを選択 > 「承認済みのリダイレクト URI」にURLを入力して保存します。

再度ローカルホストのGoogleログインボタンを押して、無事ログインできれば成功です。

以上です。

このエントリでは、ReactアプリにGoogleログインを実装する際の方法を、トラブルシューティングと共に紹介しました。

参考になった方は、ぜひ「はてブ」やSNSでシェアしていただけると嬉しいです。

Firebase HostingにReactアプリをデプロイしたい

Firebase HostingにReactアプリをデプロイしたい方は、下記エントリが参考になりそうです。

alpacat.hatenablog.com