🤦‍♂️

FlutterWebでログインを維持する

2023/04/28に公開

ローカル環境では確かめることができなかった?

authStateChangesを使用すれば、FirebaseAuthを使用して、ログインの維持をすることができるが、FlutterWebでは、なぜかできない?

実は、ブラウザーの設定が問題みたいです???
Webアプリだとローカルストレージとかに、ログインした履歴を保存しておくみたいなのですが、私のGoogleChromeの設定だと、ブラウザを閉じてしまうと、履歴が消えてしまうみたいです?

Safariで、GoogleChromeが使えるのですが、こちらでMac, iPhoneSEを使用して、動作検証をしてみたら、ログイン後の状態を覚えていました???

私の仮説ですが、ブラウザを閉じてしまうと、セッションが切れてしまっているのかもしれないと思いました?

こちらがサンプルコードです。

main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';

import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  // FirebaseUserのログイン状態が確定するまで待つ
final firebaseUser = await FirebaseAuth.instance.userChanges().first;

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final _auth = FirebaseAuth.instance;

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StreamBuilder<User?>(
        stream: _auth.authStateChanges(),
        builder: (BuildContext context, AsyncSnapshot<User?> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return CircularProgressIndicator();
          } else {
            if (snapshot.hasData) {
              return HomePage();
            } else {
              return SignInPage();
            }
          }
        },
      ),
    );
  }
}

class SignInPage extends StatefulWidget {
  
  _SignInPageState createState() => _SignInPageState();
}

class _SignInPageState extends State<SignInPage> {
  final _auth = FirebaseAuth.instance;
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();

  Future<void> _signIn() async {
    try {
      await _auth.signInWithEmailAndPassword(
        email: _emailController.text,
        password: _passwordController.text,
      );
    } on FirebaseAuthException catch (e) {
      print(e.message);
    }
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Sign In')),
      body: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: _emailController,
              decoration: InputDecoration(labelText: 'Email'),
            ),
            TextField(
              controller: _passwordController,
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            ElevatedButton(
              onPressed: _signIn,
              child: Text('Sign In'),
            ),
          ],
        ),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  final _auth = FirebaseAuth.instance;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
        actions: [
          IconButton(
            icon: Icon(Icons.logout),
            onPressed: () async {
              await _auth.signOut();
            },
          ),
        ],
      ),
      body: Center(
        child: Text('Welcome, ${_auth.currentUser!.email}!'),
      ),
    );
  }
}

こちらが実行したアプリです

Firebase Hostingして、世の中に公開した状態で動作検証しました。
こちらのサイトを参考に、Firebaseにホスティングをしました。
https://zenn.dev/snova301/books/6df29a230d681f/viewer/8d8b4a

最後に

以前、モバイルではできるのに、Webではなんでできないのだろうと躓いたので、記録を残そうと記事にしました。誰かのお役に立つと嬉しいです。

Discussion