LoginSignup
9
14

More than 3 years have passed since last update.

【React Native】ExpoでFirebase AuthenticationのSNS認証を利用する方法

Last updated at Posted at 2019-01-15

まえがき

CRNA(create-react-native-app)で作成したアプリケーションで、Firebase AuthenticationのSNS認証を行う方法をまとめます。
→こちらで紹介しているGoogleの認証方法はExpo側で廃止予定なようです。。。

GoogleアカウントとFacebookアカウントでのSNS認証を解説します。

準備

npm install create-react-native-app -g
create-react-native-app firebaseAuthSample
cd firebaseAuthSample
npm install firebase --save

Facebook認証

Facebook - Expo Documentationに実装の仕方が書かれています。

流れとして、Expo Client AppでFacebook認証を利用できるよう設定し、Expo APIで取得できるトークンでクレデンシャルを作成し、作成したクレデンシャルでログインを行います。

1. Facebook for DeveloperでIOSのBundle IDとAndroidのKey Hashesを登録する

Facebook for Developersでアプリを作成し、設定のベーシックからIOSのBundle IDAndroidのKey Hashesを登録しましょう。

IOSのBundle IDはhost.exp.Exponent、AndroidのKey HashesはrRW++LUjmZZ+58EbN5DVhGAnkX4=です。

アプリIDはあとで使うので、メモしておきましょう。

2. Firebase consoleでIOSアプリとAndroidアプリを登録する

Firebase console で「+アプリを追加」からIOSアプリとAndroidアプリを追加し、IOSアプリのバンドルIDAndroidアプリのパッケージ名host.exp.exponentを登録しましょう。

スクリーンショット 2019-01-16 1.09.52.png

3. Facebook認証を実装する

どこからでもすぐ呼び出せる用、認証処理を関数化して実装します。
Expo APIでトークンを取得、Firebase APIでトークンからクレデンシャルを取得、Firebase APIでクレデンシャルを利用してFacebook認証をさせます。

import * as firebase from 'firebase'
import * as Expo from 'expo'

const FACEBOOK_APPID = '<app id>'

const config = {
  apiKey: '<api key>',
  authDomain: '<domain>',
  databaseURL: '<database url>',
  projectId: '<project id>',
  storageBucket: '<sotarge bucket>',
  messagingSenderId: '<id>'
}

firebase.initializeApp(config)

export const authFacebook = async () => {
  try {
    const { type, token } = await Expo.Facebook.logInWithReadPermissionsAsync(
      FACEBOOK_APPID,
      { permissions: ['public_profile'] }
    )

    if (type === 'success') {
      const credential = firebase.auth.FacebookAuthProvider.credential(token)
      return firebase.auth().signInAndRetrieveDataWithCredential(credential).catch((error) => console.log(error))
    }
    else {
      return { cancelled: true }
    }
  }
  catch (e) {
    return { error: true }
  }
}

Expo APIのExpo.Facebook.loginWithReadPermissionsAsync(appId, options)で先ほどメモしたアプリIDを使用して、「token」と「type」を取得します。

※「type」には認証結果が入ります。

const { type, token } = await Expo.Facebook.logInWithReadPermissionsAsync(
  FACEBOOK_APPID,
  { permissions: ['public_profile'] }
)

「type」で認証結果をチェックして、Firebase APIのfirebase.auth.FacebookAuthProvider.credential(token)で「token」を使用して、「credential」を取得します。

Firebase APIのfirebase.auth().signInAndRetrieveDataWithCredential(credential)で「credential」を使用して、Facebook認証処理を走らせます。

if (type === 'success') {
  const credential = firebase.auth.FacebookAuthProvider.credential(token)
  return firebase.auth().signInAndRetrieveDataWithCredential(credential).catch((error) => console.log(error))
}
else {
  return { cancelled: true }
}

Google認証

Google - Expo Documentationに実装の仕方が書かれています。

流れとして、Expo Client AppでGoogle認証を利用できるよう設定し、Expo APIで取得できるトークンでクレデンシャルを作成し、作成したクレデンシャルでログインを行います。

Facebook認証の時と同じ手順です。

1. Google Developer ConsoleでIOSのバンドルIDとAndroidのパッケージ名を登録する

Google Developer Consoleで「認証情報を作成」→「OAuth クライアント ID」にてIOSのバンドルIDAndroidのパッケージ名を登録する。

IOS用とAndroid用にOAuth クライアント IDを2つ作成してください。

スクリーンショット 2019-01-16 1.30.43.png

IOS(OAuth クライアント ID)のバンドルIDとAndroid(OAuth クライアント ID)のパッケージ名はhost.exp.exponentです。

また、Android(OAuth クライアント ID)には署名証明書フィンガープリントの項目があるので、ターミナルでopenssl rand -base64 32 | openssl sha1 -cを実行し、表示された文字を入力してください。

IOSとAndroidのクライアントIDはあとで使うので、メモしておきましょう。

署名証明書フィンガープリントはA1:B2:C3...のような形式です。

2. Firebase consoleでIOSアプリとAndroidアプリを登録する

こちらはFacebook認証の2. Firebase consoleでIOSアプリとAndroidアプリを登録すると全く同じなので省略します。

※Facebook認証実装の際すでにアプリを登録しているのであれば、スキップして大丈夫です。

3. Google認証を実装する

どこからでもすぐ呼び出せる用、認証処理を関数化して実装します。
Expo APIでトークンを取得、Firebase APIでトークンからクレデンシャルを取得、Firebase APIでクレデンシャルを利用してGoogle認証をさせます。

※Facebook認証の時と仕組みは変わりません。

import * as firebase from 'firebase'
import * as Expo from 'expo'

const GOOGLE_IOS_CLIENTID = '<google ios client id>'
const GOOGLE_ANDROID_CLIENTID = '<google android client id>'

const config = {
  apiKey: '<api key>',
  authDomain: '<domain>',
  databaseURL: '<database url>',
  projectId: '<project id>',
  storageBucket: '<sotarge bucket>',
  messagingSenderId: '<id>'
}

firebase.initializeApp(config)

export const authGoogle = async () => {
  try {
    const { type, idToken, accessToken } = await Expo.Google.logInAsync({
      behavior: 'web',
      iosClientId: GOOGLE_IOS_CLIENTID,
      androidClientId: GOOGLE_ANDROID_CLIENTID,
      scopes: ['profile', 'email'],
    })

    if (type === "success") {
      const credential = firebase.auth.GoogleAuthProvider.credential(idToken, accessToken)
      return firebase.auth().signInAndRetrieveDataWithCredential(credential).catch((error) => console.log(error))
    }
    else {
      return { cancelled: true }
    }
  }
  catch (e) {
    return { error: true }
  }
}

Expo APIのExpo.Google.logInAsync(options)で先ほどメモしたIOSのクライアントIDとAndroidのクライアントIDを使用して、「idToken」と「accessToken」と「type」を取得します。

※「type」には認証結果が入ります。

const { type, idToken, accessToken } = await Expo.Google.logInAsync({
  behavior: 'web',
  iosClientId: GOOGLE_IOS_CLIENTID,
  androidClientId: GOOGLE_ANDROID_CLIENTID,
  scopes: ['profile', 'email'],
})

「type」で認証結果をチェックして、Firebase APIのfirebase.auth.GoogleAuthProvider.credential(idToken, accessToken)で「idToken」と「accessToken」を使用して、「credential」を取得します。

Firebase APIのfirebase.auth().signInAndRetrieveDataWithCredential(credential)で「credential」を使用して、Google認証処理を走らせます。

if (type === "success") {
  const credential = firebase.auth.GoogleAuthProvider.credential(idToken, accessToken)
  return firebase.auth().signInAndRetrieveDataWithCredential(credential).catch((error) => console.log(error))
}
else {
  return { cancelled: true }
}

まとめ

ExpoでFirebase AuthenticationのSNS認証を実装するときは、Expo APIで各プロバイダーのトークンを取得し、Firebase APIでトークンからクレデンシャルを取得して、クレデンシャルにて認証させれば実装できるみたいです。

9
14
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
14