FlutterへFirebase AuthenticationとGoogle Sign-Inで簡単にログイン機能を実装
はじめに
認証機能を一から作るのは大変です。
また、セキュリティに自信がないなら、自前で作らないほうが良いかと思います。(インターネットに公開したものは、容赦無く攻撃にさらされるので)
Firebase Authenticationは、Firebaseが提供する機能の一つです。
メール・パスワードによる認証だけでなく、GoogleやFacebookと連携した認証を提供してくれます。
Firebase Authenticationを使うと、簡単かつ安全にログイン機能を作りやすいです。
この記事では、Firebase Authenticationと、Googleアカウントを使った、Flutterでのログイン機能の作り方を解説します。
事前準備(Firebase Authentication)
今回はGoogleアカウントを使ったサインインを実装します。
サインイン方法を使用する前に、Firebase コンソールでサインイン方法を設定しておく必要があります。。
まず、Firebase>Authenticationへアクセスし、「ログイン方法を設定」ボタンを押します。
Googleアカウントでログインするためには、Google>有効にする、をオンにします。
プロジェクト公開名は、サービスにログインした際のGoogleからのセキュリティ通知(「お使いの Google アカウントへのアクセスが <プロジェクト参照名> に許可されました」)などで使われる、ユーザに公開されるプロジェクトの名前です。
プロジェクトのサポートメール、にもメールアドレスを設定し、保存を押します。
あとは、Googleのステータスを確認し、有効になっていればOKです。
事前準備(Flutter)
今回の実装では次のパッケージを使います。
dependencies:
flutter:
sdk: flutter
firebase_core: ^0.4.2+1
firebase_auth: ^0.15.1
google_sign_in: ^4.0.14
flutter_signin_button: ^1.1.0
pubspec.yaml
にこれらを追記たら、flutter pub get
でインストールしておきます。
また、今回はGoogle Sign-in部分について設定しておく必要があります。
google_sign_in | Flutter Package
公式サイトに従い、Info.plistにCFBundleTypeRoleと、CFBundleURLSchemesを追加します。
CFBundleURLSchemesは、array>string
部分にGoogleService-Info.plistの、REVERSED_CLIENT_IDキーをコピーして貼り付けます。
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- TODO GoogleService-Info.plistからREVERSED_CLIENT_IDキーをコピーして、
ここの値を置き換える -->
<string>com.googleusercontent.apps.861823949799-xxxxxxxxxxxxxxxxxxxxxxxxx</string>
</array>
</dict>
</array>
なお、ここで設定(書き方など)をミスっていると、google_sign_inプラグインを使う際、次のエラーが出て、アプリがクラッシュします。
Failed to send request: {"jsonrpc":"2.0","id":"100","method":"getStack","params":{"isolateId":"isolates/392598366557863"}}
Failed to send request: {"jsonrpc":"2.0","id":"101","method":"getObject","params":{"isolateId":"isolates/392598366557863","objectId":"classes/3284"}}
Failed to send request: {"jsonrpc":"2.0","id":"102","method":"invoke","params":{"isolateId":"isolates/392598366557863","targetId":"objects/629","selector":"toString","argumentIds":[],"disableBreakpoints":true}}
詳細なログを見ると、URL schemes部分でエラーが発生しています。
$ flutter run -verbose
...
...
[+26526 ms] flutter: Exception
[ ] flutter: PlatformException(google_sign_in, Your app is missing support for the following URL schemes: com.googleusercontent.apps.480616290440-xxxxxxxxxxxxxxxxxxxxxxxx, NSInvalidArgumentException, null)
[ +17 ms] Service protocol connection closed.
[ ] Lost connection to device.
[ +3 ms] DevFS: Deleting filesystem on the device (hogehoge)
[ +257 ms] Ignored error while cleaning up DevFS: TimeoutException after 0:00:00.250000: Future not completed
[ +1 ms] "flutter run" took 134,429ms.
[ +2 ms] ensureAnalyticsSent: 0ms
[ ] Running shutdown hooks
[ ] Shutdown hook priority 4
[ +1 ms] Shutdown hooks complete
[ ] exiting with code 0
Xcodeで、TARGETS>Info>URL Typesを確認して、何も値が表示されていなければ、設定をミスっているので、Xcode上でも良いので正しく設定しておきます。
(設定方法 : IOS : Login google Crash : ‘Your app is missing support for the following URL schemes: com.googleusercontent.app’ | by TungShien.com | CodeSpace69 | Medium )
実装(Flutter)
では、事前準備を終えたら、実装を進めます。
まず、main関数をasync関数にし、Fireabseを初期化します。
Future<void> main() async {
// この2行を加える
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(SignInDemoApp());
}
また、次のようなウィジェットを用意します。
class SignInDemo extends StatefulWidget {
State createState() => SignInDemoState();
}
class SignInDemoState extends State<SignInDemo> {
final _auth = FirebaseAuth.instance;
Widget build(BuildContext context) {
return Scaffold();
}
}
私はこの辺りで、次のようなエラー出て、ビルドに失敗しました。
Error: CocoaPods's specs repository is too out-of-date to satisfy dependencies.
To update the CocoaPods specs, run:
pod repo update
Error running pod install
Error launching application on iPad Pro (12.9-inch) (4th generation).
[!] CocoaPods could not find compatible versions for pod "Firebase/CoreOnly":
In snapshot (Podfile.lock):
Firebase/CoreOnly (= 6.26.0, ~> 6.26.0)
In Podfile:
cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`) was resolved to 0.14.1-3, which depends on
Firebase/CoreOnly (~> 6.33.0)
You have either:
* changed the constraints of dependency `Firebase/CoreOnly` inside your development pod `cloud_firestore`.
You should run `pod update Firebase/CoreOnly` to apply changes you've made.
CocoaPodsが依存関係の解決に失敗しているようですが、エラー画面で支持された対処方法( pod repo update
等)を試しても解決せず。
次の方法で解決することができました。
cd <Flutterプロジェクト>
cd ios
rm Podfile.lock
pod install --repo-update
cd ..
flutter clean
次に、Googleアカウントを使った、ログイン部分を実装します。
サインインボタンから、次のsignInWithGoogle()
を呼び出すことで、ログインすることができます。
// Googleを使ってサインイン
Future<UserCredential> signInWithGoogle() async {
// 認証フローのトリガー
final googleUser = await GoogleSignIn(scopes: [
'email',
]).signIn();
// リクエストから、認証情報を取得
final googleAuth = await googleUser.authentication;
// クレデンシャルを新しく作成
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
// サインインしたら、UserCredentialを返す
return FirebaseAuth.instance.signInWithCredential(credential);
}
signInWithGoogle()
を呼び出す側はこんな感じです。
onPressed: () async {
try {
final userCredential = await signInWithGoogle();
} on FirebaseAuthException catch (e) {
print('FirebaseAuthException');
print('${e.code}');
} on Exception catch (e) {
print('Other Exception');
print('${e.toString()}');
}
}
あとはアプリをビルドすると、ログインすることができます。
なお、全コードは次へ置いておきます。
FirebaseAuthentication demo using Google Sign-in in Flutter.
結果
まず、こういう画面が出るので、「Sign in with Google」をクリックし、ログインを進めていきます。
ログインを進めていくと、現時点では次のような画面が出ますが、詳細を表示>(安全でないページ)に移動をクリックします。
あとは、流れ通り確認を進めると、ログインすることができます。
参考文献
Authentication | FlutterFire
Social Authentication | FlutterFire
The OAuth 2.0 Authorization Framework
OAuth 2.0 Scopes for Google APIs | Google Identity Platform
[google_sign_in] Google sign in crashes the flutter app in IOS device · Issue #44564 · flutter/flutter
IOS : Login google Crash : ‘Your app is missing support for the following URL schemes: com.googleusercontent.app’ | by TungShien.com | CodeSpace69 | Medium
ちょっとでもセキュリティに自信がないなら、 Firebase Authentication を検討しよう - mizdev
Discussion