既に作成済みのFlutterアプリ(今回はWebアプリ)にFirebase Authentication (メールアドレス/パスワード)認証機能を利用したログイン画面を後付け(追加)した際の作業記録です。
※Firebase9以降の手順(Firebase8以前と多少設定が異なります)になります。
1.前提
・Flutterアプリ作成済み
・Firebaseプロジェクト作成済み
2.Firebase初期化(main.dart)
既存アプリのmain.dartで、Firebaseを初期化します。
(1)宣言部
①Firebase Auth パッケージ追加
・import ‘package:firebase_auth/firebase_auth.dart’; // Firebase Auth利用のパッケージ
※flutter pub add firebase_auth でパッケージインストールも実施
②Firebase 基本パッケージ追加
・import ‘package:firebase_core/firebase_core.dart’; // Firebase利用の基本パッケージ
※flutter pub add firebase_core でパッケージインストールも実施
③Firebase 構成情報ファイルのインポート
・import ‘firebase_options.dart’; // Firebaseの構成情報が含まれるファイルのインポート
④(参考)Flutter基本パッケージ追加
・import ‘package:flutter/foundation.dart’; // (参考)デバッグビルドで利用します
※flutter pub add foundation でパッケージインストールも実施
⑤(参考)ログイン画面インポート
・import ‘screen/login.dart’;
(2)main( ) { }
①Flutterの初期化
他のサービスやリソースを使用する前に、正しく初期化されていることを保証します。
(例:非同期操作(Firebaseの初期化やローカルデータベースのセットアップなど)の前処理、ウィジェットシステムの安定性確保)
Flutterアプリケーションで一般的に行われるパターンであり、特に非同期処理を伴う初期設定で重要。
・WidgetsFlutterBinding.ensureInitialized();
②Firebaseの初期化
プラットフォーム固有のオプションを読み込めるようになります。
・ await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
③(参考)デバッグビルド設定/ローカルエミュレータ接続
開発中のデバッグモード実行時のみ、ローカルエミュレータに接続するようになります。
if(kDebugMode){ // デバッグビルドのみで実行
await FirebaseAuth.instance.useAuthEmulator(‘localhost’, 9099);
}
※kDebugMode:
true ← IDEのデバッグモード実行、flutter run -d chrome、等
false ← リリースモード実行(flutter run –release、flutter run –profile、flutter build apk、等
④main( ) の未来・非同期化
main( ) をFuture<void> main( ) async { } とします。
3.(ログイン画面への)画面遷移の指定
main( ){ } 中の runApp( ) で起動するエントリーポイントクラス中の Widget build の return で、以下の遷移指定を行います。これにより既存アプリ表示前に、ログイン画面が表示されるようになります。
(例)
・initialRoute: ‘/’,
routes: {
’/’: (context) => const LoginScreen(),
’/home’: (context) => const DialogExample(title: ‘Task Lists’),
},
4.ログイン画面作成
上記で指定した遷移先のログイン画面を作成します。
(例)
import 'package:firebase_auth/firebase_auth.dart'; // Firebase Authentication API
import 'package:flutter/material.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({super.key}); // Keyパラメータを追加
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
@override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
// ログイン処理
@override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: const Text('Login Screen'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
TextFormField(
controller: _emailController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
labelText: 'Email address',
),
),
TextFormField(
controller: _passwordController,
keyboardType: TextInputType.visiblePassword,
decoration: const InputDecoration(
labelText: 'Password',
),
obscureText: true,
),
ElevatedButton(
onPressed: _signInWithEmailAndPassword,
child: const Text('Login'),
),
],
),
),
);
}
void _signInWithEmailAndPassword() async {
try {
// Firebase機能(ログイン)を使用してメールアドレスとパスワードでログイン)
final userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailController.text.trim(), // 空白を取り除く
password: _passwordController.text.trim() // 空白を取り除く
);
// 修正)LoginScreenでのログイン成功後の処理を以下のように変更
// これにより、ログインに成功した後にDialogExample画面(ホーム画面)
// に遷移するようになります。
// ログイン成功
if( userCredential.user != null) {
// ignore: use_build_context_synchronously
Navigator.pushReplacementNamed(context, '/home'); // ホーム画面に遷移
}
} on FirebaseAuthException catch (e) {
// ログイン失敗
final errorMessage = e.message ?? 'An error occurred during login.';
debugPrint('errorMessage : $errorMessage');
// ignore: use_build_context_synchronously
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(e.message!),
),
);
}
}
}
5.ウェブアプリにFirebaseを追加
①Webアプリ追加を選択
②「アプリの登録」画面で、各設定(下図)後、「アプリを登録」を選択。
③「Firebase SDKの追加」画面を確認
※以下はFirebaseコンソールのウィザードに沿った手順だが、(ウィザードを見なくても)サイト(https://firebase.google.com/docs/web/setup?hl=ja#available-libraries)に詳細手順が記載されている。
④最新のFirebase SDKインストール
> npm install firebase
⑤Web\index.htmlをFirebase初期化
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "[mask]AIzaSyCuyu1pw9M_4p6BaTrKQTMc2Q8YCyxkTbs[/mask]",
authDomain: "[mask]mypj001-edb94[/mask].firebaseapp.com",
projectId: "[mask]mypj001-edb94[/mask]",
storageBucket: "[mask]mypj001-edb94[/mask].appspot.com",
messagingSenderId: "[mask]252454792180[/mask]",
appId: "[mask]1:252454792180:web:3ea1ed55b5843a4ca8e7a1[/mask]",
measurementId: "[mask]G-BEXRBCVVH0[/mask]"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
具体的には以下の様に、元のindex.htmlを修正する。
(但し上記書式(import等)はJS向け。以下はHTML向けの表記にしてある。
→詳細URL:「window から互換ライブラリを使用する」参照。
また上記はanalyticsを例に利用する前提で書かれているが、ここではauthenticationに置換える。)
・<html> → <html lang=”ja”> ※言語指定
・<head>
↓
<head>
※モバイルデバイス上でのウェブページの表示を適切に制御するため↓
(これによりHTML冒頭のワーニングが消える)
<meta name=”viewport” content=”width=device-width, initial-scale=1″>
※Firebase JavaScript SDKのインクルード↓
// Firebase共通のSDK
<script src=”https://www.gstatic.com/firebasejs/9.14.0/firebase-app.js”></script>
// Firebase Authentication機能のSDK
<script src=”https://www.gstatic.com/firebasejs/9.14.0/firebase-auth.js”></script>
(※詳細URL:window から互換ライブラリを使用する)
・<body>
↓
<body>
※Firebaseプロジェクトの初期化
<script>
// このWebアプリのFirebase構成情報
const firebaseConfig = {
apiKey: “YOUR_API_KEY”,
authDomain: “YOUR_AUTH_DOMAIN”,
projectId: “YOUR_PROJECT_ID”,
storageBucket: “YOUR_STORAGE_BUCKET”,
messagingSenderId: “YOUR_MESSAGING_SENDER_ID”,
appId: “YOUR_APP_ID”
};
// Firebaseプロジェクトの初期化
const app = initializeApp(firebaseConfig);
// Authenticationサービスの参照を取得
const auth = getAuth(app);
</script>
⓺Firebase CLI のインストール
> npm install -g firebase-tools
⑦Firebase Hosting へのデプロイ
> firebase login
> firebase init
⑧FlutterプロジェクトでFirebaseをセットアップ
> flutterfire configure
FirebaseプロジェクトとFlutterプロジェクトを結びつけ、firebase_options.dart
を含む必要な設定ファイルを自動生成します。
※lib
フォルダ直下に firebase_options.dart
ファイルが生成されているか確認します。
6.ローカルエミュレータによる事前動作確認
上記5の後、すぐに(Firebaseに)デプロイするのではなく、その前に、ローカルエミュレータによる動作確認を行います。
①エミュレータ起動
> firebase init emulators
> firebase emulators:start
②ユーザー登録
ユーザー登録画面でログイン情報(メールアドレス/パスワード)を設定します。
③デバッグモード実行
(前手順までに既に(デバッグモード実行の場合)ローカルエミュレータによる動作確認が出来る様に、コードを記述してあるので)次のコマンドで実行します。
> flutter run -d chrome
④ログイン画面表示の確認
以下の様にログイン画面が表示されます。
⑤ログイン動作確認
以下の様に、ログイン情報入力後、メイン画面が表示されれば、成功です。
以上でローカルエミュレータによる動作確認は完了です。
以降の手順で、Firebaseにデプロイすることになります。
7.ビルドおよびデプロイ用フォルダへの格納
①webアプリモードでビルドします。
> flutter build web
②build\webフォルダ直下を確認
ビルド後のプロダクトが出来ていることを確認します。
③上記プロダクトを、publicフォルダ直下にコピーします。
8.Firebaseへのデプロイ、表示確認
①上記プロダクトをfirebaseにデプロイします。
> firebase deploy
②上記URL(赤い囲み)をブラウザで表示します。
以下の様にログイン画面が表示されました。
9.ログイン動作確認
①Authenticationコンソールでログイン情報を登録します。
②上記登録情報で、ログイン確認します。
以下の様に、ログイン後、メイン画面が表示されれば成功です。
以上で、既存Flutter(Web)アプリに、Firebase Authentication (メールアドレス/パスワード認証)によるログイン画面を追加する手順は完了です。
10.補足
10-1.接続先の決定方法について
Firebase プロジェクトに関連付けて、Firebase Authentication機能を実装させた、Flutterアプリ(Webアプリ)を(ローカル環境で、Firebase Emulators Sweet を実行後に)デバッグモード実行させたら、(Emulatorsに接続するコードを記載したので、当然)ローカル環境におけるエミュレータに接続しました。
また、そのアプリをビルド(flutter build web)して、Firebaseにデプロイ(hosting機能を利用)し、そのURLをブラウザで表示させたら、FirebaseサーバーのAuthentication機能に、接続に行きました。
では、そのビルドしたアプリを、ローカル環境のIIS上にデプロイして動作させた場合、そのアプリは、Firebaseサーバーに接続しに行くのでしょうか?それともエミュレータを探してしまうのでしょうか?
答えは(Flutterアプリ(Webアプリ)をローカル環境のIIS(Internet Information Services)上にデプロイして実行した場合)Firebase Authentication機能を利用しているコード部分で、ローカルのエミュレータへの接続を明示的に指定していない限り、アプリはFirebaseサーバーに接続し、Firebaseの本番環境の認証機能を使用します。
上記のアプリでは、デバッグモード実行時のみ、エミュレータに接続し、そうでない場合は、Firebaseサーバーに接続しに行く様に、コードを編集してありましたので、このように動作します。
つまり、Firebaseの初期化コード(例:Firebase.initializeApp()
)が本番設定を使用しているためです。
IIS上にデプロイしても・・・
ログイン認証画面は表示され・・・
Firebase Auth 認証されてログインできました。
お疲れ様でした。
次回は、Androidアプリの場合の手順です。