この記事はReact Native Advent Calendar 2019の24日目の記事です。
#はじめに
メリークリスマス! @mediaboxes です!
待ちに待ったクリスマスイブ24日!?実は先日失恋した僕にサンタさんがプレゼントで24日のAdventCalendarを前日(23日)にくれたので殴り書します!乱筆乱文失礼致します。それでも僕は元気です。
と、言うことで、僕の会社ではエンターテイメント系アプリからライフログ系アプリをReactNativeで数本開発と運用してきました。
もともとNativeでアプリを少人数で開発してきたのですが、iOSとAndroidの両方のソースコードやレイアウトを別々で作るのがバカらしくてReactNativeを採用しました。なので、Nativeのプロジェクトではないexpo init
よりreact-native init
がメインが馴染み深いです。
なのでReactNative(非expo)版のFirebase authとSign in with Appleについてまとめます!
#Sign in with Appleについて(ざっくりだよ)
ソーシャルログインを使っているアプリの場合に対応が必要になります。リジェクトなど注意してください
##何ができるの?
- AppleIDでアプリやwebにログインできる
- 本メールアドレス隠して擬似メールアドレスでサービスに情報提供できる
##制約
- FacebookやGoogle、twitterのソーシャルログインを使ってるアプリは、Sign in with Appleを実装する必要がある
- 2019年9月12日以降は新規リリースアプリはガイドラインに従う必要がある ※もう新しいアプリは対応が必要
- 2020年4月以降は既存アプリもガイドラインに従う必要がある ※既存のアプリは今後必要
##公式ガイドライン
ガイドラインの公式の詳しいお知らせはこちらをご確認ください
https://developer.apple.com/news/?id=09122019b
#実装
前提
iOS13以上のアプリのみ対応。
iOS13未満やAndroidは今回は非対応で、Sign in with Appleのボタンを表示しないで他のログインを選択してもらいます。WebviewなどでSign in with Apple JSを使う方法などあるそうですが、今回は未検証です。
ReactNative のバージョンはv0.615を使用
@react-native-firebase/app,@react-native-firebase/auth モジュールはv6を使用
下準備
Firebasesのプロジェクトを設定をSign In with Appleを有効にする
firebase上のアプリの設定は完了しているものとします。
Firebases consoleのAuthentication/ログイン方法にあるAppleを有効にします。
※いつの間にかBetaの表記が消えましたね!
AppleDeveloperの App ID ConfigurationでSign In with Appleを有効にする
XcodeのprojectのSign In with Appleを有効にする
Xcode11以上でSigning&Capabilitiesにある、+Capabolotyをクリックして表示された中にあるSign In with Appleをダブルクリックすると有効になる
###@react-native-firebas/appがプロジェクトにない場合はインストールする
https://invertase.io/oss/react-native-firebase/
ReactNativeでFirebaseを使う時によく使われるモジュール。
多くの機能をカバーしていますがバージョンの変化も早いのでご注意を。
react-native-firebaseのインストールは公式のこちらを参考に
https://invertase.io/oss/react-native-firebase/quick-start/
###@react-native-firebase/authがプロジェクトにない場合はインストールする
react-native-firebaseは多くの機能があるので、必要な機能ごとにモジュールをインストールする必要です。今回使用するfirebase authの用のモジュールのインストールは公式のこちらを参考に
https://invertase.io/oss/react-native-firebase/v6/auth/quick-start/
@invertase/react-native-apple-authenticationをインストールする
各ソーシャルログインで認証後にトークンをfirebaseに渡す(credentialを作成)と統合されたfirebaseIDが発行されます(signInWithCredential)。
このfirebaseIDを利用することで、facebook,twitter,googleを気にせずユーザー管理が行えます。
Sign In with Appleの認証を @invertase/react-native-apple-authentication
で行います。
ボタン用のコンポーネントも準備されているのでそのまま使うましょう。
ReactNativeの実装
@react-native-firebase/authが最近更新されて、Sign In with Appleの実装方法が記載されました。
https://invertase.io/oss/react-native-firebase/v6/auth/social-auth/
他に、Facebook、Twitter、Googleの実装方法が記載されていますので参考に。
今回は、iOS13未満やAndroidの為に、GoogleSigninも一緒に実装した例を参考に記載しておきます。
処理の流れ
onSignInGoogleで、google認証→credential作成
onSignInAppleで、apple認証→credential作成
↓
credentialでfirebase authにログイン(signInWithCredential)
↓
firebase.auth().currentUserを使って、自前のログイン処理を書く
import * as React from "react";
import { View } from "react-native";
import { Container, Content, Text } from "native-base";
import { firebase } from "@react-native-firebase/auth";
import {
GoogleSignin,
GoogleSigninButton
} from "@react-native-community/google-signin";
import appleAuth, {
AppleButton,
AppleAuthRequestScope,
AppleAuthRequestOperation
} from "@invertase/react-native-apple-authentication";
import { errorAlert } from "../utils";
export default class LoginScreen extends React.Component {
//Google認証
onSignInGoogle = async () => {
try {
let data;
try {
data = await GoogleSignin.signIn();
} catch (error) {
throw new Error("ログインに失敗しました");
}
const credential = firebase.auth.GoogleAuthProvider.credential(
data.idToken,
data.accessToken
);
await this.onSignIn(credential);
} catch (error) {
errorAlert(error.message);
}
};
//Apple認証
onSignInApple = async () => {
try {
let data;
try {
data = await appleAuth.performRequest({
requestedOperation: AppleAuthRequestOperation.LOGIN,
requestedScopes: [
AppleAuthRequestScope.EMAIL,
AppleAuthRequestScope.FULL_NAME
]
});
} catch (error) {
throw new Error("ログインに失敗しました");
}
const credential = firebase.auth.AppleAuthProvider.credential(
data.identityToken,
data.nonce
);
await this.onSignIn(credential);
} catch (error) {
errorAlert(error.message);
}
};
//signInWithCredential
onSignIn = async credential => {
try {
const firebaseuser = await firebase
.auth()
.signInWithCredential(credential);
const user = firebase.auth().currentUser;
// ***********
// user.uidを使ってアカウント処理
// ***********
} catch (error) {
errorAlert(error.message);
}
};
render() {
return (
<Container>
<Content>
<View>
<View>
<Text>ログイン</Text>
<GoogleSigninButton
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={this.onSignInGoogle}
/>
{appleAuth.isSupported ? (
<AppleButton
buttonStyle={AppleButton.Style.WHITE_OUTLINE}
buttonType={AppleButton.Type.SIGN_IN}
onPress={this.onSignInApple}
/>
) : null}
</View>
</View>
</Content>
</Container>
);
}
}
#まとめ
失恋をバネに初めての投稿させてもらいました。機会がありましたらまた投稿していきます。