Firebase Authentication Googleサインイン
対話システムを構築する際に、個人認証は必須となります。そこで、今回はFirebaseのAuthentcation機能を使って、ログイン機能を作ってみたいと思います。
Firebaseの認証機能では、様々な認証が用意されています。メールアドレスとパスワードを使ってユーザ登録とログインをする方法がよく使われています。しかし、新たにユーザ登録するのは面倒かもしれません。今ではほとんどの方が、GoogleもしくはAppleのIDをお持ちだと思いますので、まずは、Google認証にチャレンジします。以下は、基本的にWebアプリを前提としてます。
Firebaseコンソールでの設定
Googleプロバイダの追加
Firebaseコンソールにログインして、サイドメニューの「構築」から「Authentication」を選択します。
Sign-in methodタグの「新しいプロバイダ」ボタンをクリックしてGoogleを追加します。
Googleプロバイダを有効にしたら、ウェブSDK構成を開いて、ウェブクライアントIDを確認してメモしておきます。
承認済みドメインの追加
Settingsタブで「承認済みドメイン」を追加します。localhost と、Firebase のHositingサイトは自動で設定されていますので、必要に応じて追加しておきます。
firebaseコンソールでの設定は、以上の2ヶ所です。
Flutter アプリ側の設定
こちらの記事を参考にfirebase SDKをインストールして初期化しておきます。
flutterfire_cliを使ってconfigureすると、lib/firebase_options.dartが生成されます。ここには、Firebaseをinitializeするときのオプションが定義されています。
プラグインをインストールします。
flutter pub add firebase_core
flutter pub add firebase_auth
iOS,Androidのアプリの場合には、google_sign_in プラグインもインストールしますが、webアプリの場合には不要です。
コードにプラグインをインポート
import 'package:firebase_auth/firebase_auth.core';
import 'package:firebase_auth/firebase_auth.dart';
Google認証サンプルコード
Google認証の最低限のサンプルコードは、以下の通りです。 画面上のLoginをクリックすると、認証用のpopupが表示されます。認証が成功すれば、Chat画面(仮)に遷移し、 userのdisplayNameが表示されます。 Loginしたユーザは、FirebaseのAuthenticationのusersからログイン日時などが確認できます。
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'src/chat.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const LoginPage(title: 'Flutter Demo Home Page'),
);
}
}
class LoginPage extends StatefulWidget {
const LoginPage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<LoginPage> createState() => _loginPageState();
}
class _loginPageState extends State<LoginPage> {
// Googleアカウントの表示名
String infoText = '';
// 公式ページのコードをそのままコピー
Future<UserCredential> signInWithGooglePopup() async {
// Create a new provider
GoogleAuthProvider googleProvider = GoogleAuthProvider();
googleProvider
.addScope('https://www.googleapis.com/auth/contacts.readonly');
googleProvider.setCustomParameters({'login_hint': 'user@example.com'});
return await FirebaseAuth.instance.signInWithPopup(googleProvider);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
TextButton(
onPressed: () async {
try {
await signInWithGooglePopup();
final User? user = FirebaseAuth.instance.currentUser;
if (user != null) {
await Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) {
return ChatPage(user);
}),
);
}
} catch (e) {
setState(() {
infoText = 'Loginに失敗しました:${e.toString()}';
});
}
},
child: const Text(
'login',
style: TextStyle(fontSize: 50),
),
),
Text(infoText), // loginされなかった時のメッセージを表示
]),
));
}
}
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'main.dart';
// チャット画面用Widget
class ChatPage extends StatelessWidget {
ChatPage(this.user);
final User user;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('チャット'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.logout),
onPressed: () async {
await FirebaseAuth.instance.signOut();
// ログイン画面に遷移+チャット画面を破棄
await Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) {
return LoginPage(title: 'Login Page');
}),
);
},
),
],
),
body: Center(
// ユーザー情報を表示
child: Text('ログイン情報:${user.displayName}'),
),
);
}
}
localhostでテストする場合には、承認済みのドメインとポート番号を合わせる必要があります。
承認済みドメインが https://localhost:5000の場合は、
flutter run --web-port 5000
と、ポート番号を指定して起動する必要があります。