はじめに
Expo + Firebaseで、下記のような一般的な構成のユーザー認証機能を実装してみたいと思います。
- メールアドレス/パスワードでログイン
- メールアドレス/パスワードでユーザー新規登録(初めての方)
- Googleアカウントを使ってログイン
- ログアウト
1. 基本設定
Firebaseのコンソール画面でWebアプリを追加し、スニペットをコピーしてfirebaseConfig
をファイル化しておきます。Githubにアップされないように、今回は.env
に記載したものをreact-native-dotenv
で読むこむようにします。
FIREBASE_API_KEY=<apiKey>
FIREBASE_AUTH_DOMAIN=<authDomain>
FIREBASE_DATABASE_URL=<databaseURL>
FIREBASE_PROJECT_ID=<projectId>
FIREBASE_STORAGE_BUCKET=<storageBucket>
FIREBASE_MESSAGING_SENDER_ID=<messagingSenderId>
FIREBASE_APP_ID=<appId>
FIREBASE_MEASUREMENT_ID=<measurementId>
import {
FIREBASE_API_KEY,
FIREBASE_AUTH_DOMAIN,
FIREBASE_DATABASE_URL,
FIREBASE_PROJECT_ID,
FIREBASE_STORAGE_BUCKET,
FIREBASE_MESSAGING_SENDER_ID,
FIREBASE_APP_ID,
FIREBASE_MEASUREMENT_ID
} from 'react-native-dotenv';
export default {
apiKey: FIREBASE_API_KEY,
authDomain: FIREBASE_AUTH_DOMAIN,
databaseURL: FIREBASE_DATABASE_URL,
projectId: FIREBASE_PROJECT_ID,
storageBucket: FIREBASE_STORAGE_BUCKET,
messagingSenderId: FIREBASE_MESSAGING_SENDER_ID,
appId: FIREBASE_APP_ID,
measurementId: FIREBASE_MEASUREMENT_ID
};
これを使ってクライアント側でfirebase
モジュールを初期化し、
auth()
メソッドでAuthクラスのインスタンスを取得します。
import firebase from 'firebase';
import firebaseConfig from './firebaseConfig';
firebase.initializeApp(firebaseConfig);
export const auth = firebase.auth();
export default firebase;
onAuthStateChanged
で認証状況が変化したらユーザー情報をstateに保持するようにしておきます。
シンプルなRedux実装に組み込むとしたらこのような感じになるかと思います。
auth.onAuthStateChanged((user) => {
console.log('auth state changed', user);
const current = store.getState().user.data;
if (!current && user) {
store.dispatch({
type: 'SUCCESS_AUTH_USER',
data: user
});
} else if (current && !user) {
store.dispatch({
type: 'SIGN_OUT_USER'
});
}
});
2. メールアドレス/パスワードで新規登録
Firebaseのコンソール画面で「開発」→「Authentication」→「ログイン方法」→「ログインプロパイダ」から「メール / パスワード」を有効にします。この画面で有効なログイン方法を設定することができます。
画面コンポーネント内、stateにemail
とpassword
の値があり、ボタンを押したらauthUser
アクションをdipatchするとします。
export const authUser = (email, password) => (dispatch) => {
dispatch({
type: 'START_AUTH_USER'
});
auth.createUserWithEmailAndPassword(email, password)
.catch(({ message }) => {
dispatch({
type: 'FAIL_AUTH_USER',
message
});
});
};
createUserWithEmailAndPassword
メソッドにメールアドレスとパスワードを渡すだけです。
これでユーザーが新規登録され、ユーザーオブジェクト(user)がstateにsetされます。
Firebaseのコンソール画面でユーザーが追加されているのがわかるはずです。
3. ログアウト
FirebaseAuthではデフォルトだと認証状態が保持されるような設定になっています(詳しくはこちら)。
このままでは開発しにくいので、ログアウト機能を先に実装しておきたいと思います。ボタンを押したらsignOut
アクションをdispatchするとします。
export const signOut = () => (dispatch) => {
dispatch({
type: 'START_SIGN_OUT_USER'
});
auth.signOut()
.catch(({ message}) => {
Alert.alert(message);
});
};
4. メールアドレス/パスワードでログイン
今度は先ほど作成したユーザーにログインしてみます。こちらも新規登録と同様に、
export const signIn = (email, password) => (dispatch) => {
dispatch({
type: 'START_AUTH_USER'
});
auth.signInWithEmailAndPassword(email, password)
.catch(({ message}) => {
dispatch({
type: 'FAIL_AUTH_USER',
message
});
});
};
ここまでは非常に簡単です。
5. Googleアカウントを使用してログイン
Googleログインについては2019年10月現在、2通りの方法がありますが、最新の方法はExpoClientでの開発に対応していませんので、ひとまず非推奨の旧式の方法を紹介します。
こちらの方法はFirebaseでは完結せず、Developpers Consoleでプロジェクトを作成し、認証情報を追加する必要があります。
「認証情報」タブ→「認証情報を作成」→「OAuthクライアントID」を選択しクライアントIDを作成します。Androidの場合はパッケージ名
を、iOSの場合はバンドルID
をhost.exp.exponent
と入力します。
作成したクライアントIDはJSから使用するので、.env
ファイルに追記しておきます。
GOOGLE_AUTH_IOS_CLIENT_ID=<IOS_CLIENT_ID>
GOOGLE_AUTH_ANDROID_CLIENT_ID=<ANDROID_CLIENT_ID>
また、「OAuth同意画面」タブから最低限サポートメールアドレスを設定しておきましょう。これがないと認証エラーが発生します。
ではアプリ側です。
認証に必要なexpo-google-app-auth
モジュールをインストールします。
$ yarn add expo-google-app-auth
authGoogle
アクションをdispatchするとして、実装してみます。
import Google from 'expo-google-app-auth';
export const authGoogle = () => (dispatch) => {
dispatch({
type: 'START_AUTH_USER'
});
Google.logInAsync({
behavior: 'web',
iosClientId: GOOGLE_AUTH_IOS_CLIENT_ID,
androidClientId: GOOGLE_AUTH_ANDROID_CLIENT_ID,
scopes: ['profile', 'email']
}).then((result) => {
if (result.type === 'success') {
const { idToken, accessToken } = result;
const credential = firebase.auth.GoogleAuthProvider.credential(idToken, accessToken);
auth.signInWithCredential(credential)
.catch(({ message }) => {
dispatch({
type: 'FAIL_AUTH_USER',
message
});
});
} else {
dispatch({
type: 'FAIL_AUTH_USER',
message: result.type
});
}
}).catch(({ message }) => {
dispatch({
type: 'FAIL_AUTH_USER',
message
});
});
};
実行すると、アプリ画面にはダイアログが表示された後Googleのログイン画面が表示されます。
これでGoogleアカウントと作成したAuthユーザー(既存ユーザーでも)が紐づけられます。
Github
Authenticationを含め、メールアドレス・電話番号認証やFirestoreなども使用したサンプル
https://github.com/mildsummer/expo-auth-practice
参考
Getting started with Firebase Authentication on React Native
Firebaseアプリをデプロイ後、Googleログインしようとすると403エラーがてたときの対処方法。