概要
Flutterアプリに認証を入れたいのでFirebaseと連携することにしてみたら思いのほか爆速で作れた話。
FlutterとFirebaseの連携を調べてたら、やれSDKを入れるやら、google-service.jsonを入れるやらの情報が出てきたりでめんどくさい印象だったんですが、、、
公式の手順をそのままやったら爆速でできました。
いや、そりゃ公式の手順に沿ってやれよって話なんですけどね
環境
基本的には以下の公式手順から「Test Drive」まで済ませています。
また、以下の環境で進めて行きます。
- OS:Windows11
- エディタ:VScode
- アプリの実行はAndroidエミュレータを使用
流れ
基本的には公式の手順のとおりですが。
Flutterプロジェクトの作成
VScodeのコマンドパレットから「Flutter: New Project」でプロジェクトを作成します。
作成できたらF5(もしくはflutter run
コマンド)でAndroidエミュレータ上でFlutterアプリが動くか確認してください。
FirebaseとFlutterの連携
FirebaseとFlutterを連携できるようにします。
Firebase-CLIの導入
まずCLIツールを以下を参考に導入します。
VScode上で開発する都合があるので、npmからインストールします。
npm install -g firebase-tools
インストールできたら、手順に従いログインとプロジェクト一覧が表示できることを確認します。
$ firebase login
>> ブラウザからログインする
# firebase projects:list
>> プロジェクト一覧が表示されることを確認
FlutterにFirebaseを追加
以下の手順を参考に導入します。
以降はFlutterプロジェクトディレクトリ直下で実行してください
まず、FlutterとFirebaseを連携するために必要なflutterfire_cliをインストールします。
このCLIツールがつよつよです。
dart pub global activate flutterfire_cli
次にFirebaseとの連携をセットアップします。
flutterfire configure
Firebaseプロジェクトの作成
create a new project
を選択し、新規にFirebaseプロジェクトを作成します(既存のものも選択可能)
プロジェクト名が既に使われている場合は作成できないので注意
セットアップするプラットフォームの選択
対象のアプリがどのプラットフォーム(Android / iOSとか)をサポートするかを選択します。
選択したプラットフォームがFirebase上に自動的にセットアップされます。
今回はAndroidアプリなのでandroid
のみを残します。
成功するとその旨がターミナル上に表示され、lib/firebase_options.dart
が作成されます。
続いて、最低限必要なfirebase_core
をインストールしておきます。
flutter pub add firebase_core
また、Firebaseの管理画面上にプロジェクトとAndroidアプリが登録されていることが確認できます。
ここまででFlutterでFirebaseを使うすべての準備は完了です。
汎用的な手順でやろうとすると、GUIからプロジェクト作ってアプリ登録して、SDKを入れるためにgoogle-service.jsonをDLしてFlutterプロジェクトに配置して、、という感じですが、それらの手順をすべて省くことができます。
動作確認
main.dart
を以下のようにします。コードのポイントとしては以下のとおり
- main()にFirebaseの初期化コード
Firebase.initializeApp
を追記 -
Firebase.initializeApp
が非同期で処理するのでmain()
にasync
を追加 - 非同期処理の初期化のため
WidgetsFlutterBinding.ensureInitialized();
を実行するようにする
import 'package:flutter/material.dart';
// firebase関連のパッケージをインポート
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
// Firebaseの初期化を非同期で行うので、main()にasyncを追加
void main() async {
// 非同期処理の初期化
WidgetsFlutterBinding.ensureInitialized();
// Firebaseの初期化
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Hello Flutter'),
),
body: Center(
child: Text('Hello Flutter'),
),
),
);
}
}
一旦これで動くことを確認してください。
ひとまずエラーなくアプリの画面が出ればOKです。
VScodeのF5(デバッグモード)でうまく動作しない場合、ターミナルから直接flutter run
コマンドを打って立ち上げてください。何故かそういう現象が発生したときがありました。環境の問題とは思いますが・・・
Firebaseの認証を利用できるようにする
Firebaseで認証ができるようにします。まずは画面を作ります。
ログイン画面の作成
main.dart
を以下のように修正します。ポイントは以下のとおりです。
- ログインID・パスワードの入力欄を作成
- ログインIDとパスワードの入力値を取得して使わないといけないので、MyAppをStatefullWidgetに変更します。
- 入力欄の変更を検知し、入力内容を変数に格納します。
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
void main() async {
// Firebaseの初期化を待機
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
// ログインID・パスワードの値を使うのでStatefullWidgetに変更
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
// ログインID
String LoginEmail = "";
// パスワード
String LoginPassword = "";
// ログインメッセージ
String LoginMessage = "Not Login";
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Hello Flutter'),
),
body: Container(
padding: EdgeInsets.all(16),
child: Column(
children: [
// メールアドレス入力欄
TextFormField(
decoration: InputDecoration(labelText: "メールアドレス"),
onChanged: (String inputValue) {
// 値が変更された際に入力内容を変数に保持
setState(() {
LoginEmail = inputValue;
});
},
),
// パスワード入力欄
TextFormField(
decoration: InputDecoration(labelText: "パスワード"),
obscureText: true,
onChanged: (String inputValue) {
// 値が変更された際に入力内容を変数に保持
setState(() {
LoginPassword = inputValue;
});
},
),
ElevatedButton(
onPressed: () {
},
child: Text("Auth"),
),
Text(LoginMessage)
],
),
),
),
);
}
}
実行できるか確認します。以下のような画面で立ち上がればOKです。
ログイン機能を追加する
Firebaseのログイン処理の追加
ElevatedButton
のonPress
処理にFirebaseを使って認証をする処理を追加します。
認証にはFirebaseAuth.instance.signInWithEmailAndPassword
を使います。
import 'package:firebase_auth/firebase_auth.dart';
FirebaseAuth.instance.signInWithEmailAndPassword(email: [メールアドレス], password: [パスワード])
まず、必要なパッケージをインストールします。
flutter pub add firebase_auth
次に、ログインボタンのonPressed
に処理をFirebase認証処理を追加します。
コードのポイントとしては、以下のとおりです。
- Firebaseへの認証を非同期
(await)
で実行するので、onPressed
でasync関数を実行します。 - 認証結果をUserCredentialプロパティで受け取ります。
- 認証成功時にはUserプロパティでログインユーザーを取得します。
- try-catchで認証失敗時には例外処理を実装しています。
//...
ElevatedButton(
onPressed: () async {
try {
// Firebase認証処理
final UserCredential result = await FirebaseAuth.instance
.signInWithEmailAndPassword(
email: LoginEmail, password: LoginPassword);
// ログイン成功時にはユーザーを取得
final User user = result.user!;
setState(() {
LoginMessage = "LOGIN SUCCEED - ${user.email}";
});
} catch (e) {
// ログイン失敗時
setState(() {
LoginMessage = "LOGIN FAILED - ${e.toString()}";
});
}
},
child: Text("Auth"),
),
//...
Firebaseにログインアカウントを設定する
Firebaseの管理画面からログインについての設定を行います。
「Authentication」の画面を開き、ログインプロバイダからメール / パスワードを選択して有効化します。
次にメール・パスワードの追加を行います。「User」タブからメール / パスワードユーザーを追加します。
値はひとまずダミーのもので構いません。
動作確認
準備が整ったのでFirebaseによる認証を検証します。
Flutterアプリを立ち上げ、メールアドレスとパスワードを入れて認証します。
正しいメールアドレスとパスワードで認証
LOGIN SUCCEEDとなれば認証成功です。
間違ったメールアドレスとパスワードで認証
LOGIN FAILEDとなり、認証失敗のエラーが表示されます。
ここからできること
この記事では書きませんけど、ここまでできたら以下のこともできます。
- Firebaseの他のサービスの利用(Database / Storage / Functionなどなど)
- ログイン処理後にナビゲーションを設定して他の画面に遷移
おわり
ネットでかじった情報じゃなくて公式の手順読めよっていうだけの記事なんですけどね。
ほら、新しい電化製品買っても説明書は読まないですよね?俺は読まない