📌

[Flutter] google_sign_in_webのsignIn関数がdeprecated 認証&FirebaseAuthにサインイン

2024/03/22に公開

問題点

google_sign_in_web の signIn関数 が使えなくなるとのこと

Use `signInSilently` and `renderButton` to authenticate your users instead.
Read more: https://pub.dev/packages/google_sign_in_web
The google_sign_in plugin `signIn` method is deprecated on the web, and will be removed in Q2 2024. Please use `renderButton` instead. See: https://pub.dev/packages/google_sign_in_web#migrating-to-v011-and-v012-google-identity-services

解決策

以下のコードをコピペすれば動きます。

dart
import 'dart:async';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in_web/google_sign_in_web.dart';

class SignUpScreen extends StatefulWidget {
  const SignUpScreen({super.key});

  @override
  State<SignUpScreen> createState() => _SignUpScreenState();
}

class _SignUpScreenState extends State<SignUpScreen> {
  late GoogleSignInPlugin? plugin;

  @override
  void initState() {
    super.initState();
    initGoogleSignInPlugin(); // await を使わずに非同期処理を「開始」する
  }

  // GoogleSignInPlugin の初期化
  void initGoogleSignInPlugin() async {
    plugin = GoogleSignInPlugin();
    await plugin?.init();
    await listenToUserDataEvents();
  }

  // 認証情報の更新を監視
  Future<void> listenToUserDataEvents() async {
    plugin?.userDataEvents?.listen((userData) async {
      // 認証情報が取得できない場合は何もしない
      if (userData == null) {
        return;
      }

      if (userData.idToken != null) {
        final signInTokenData = await plugin?.getTokens(email: userData.email);

        //  FirebaseAuth にログイン
        final auth = FirebaseAuth.instance;
        await auth.signInWithCredential(
          GoogleAuthProvider.credential(
            idToken: userData.idToken,
            accessToken: signInTokenData?.accessToken,
          ),
        );
      }
    });
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text('ログイン画面'),
        ),
        body: Center(
          child: plugin?.renderButton(), // Google SignIn ボタンを表示
        ),
      );
}

詳細

以下の手順で認証が行われます

  1. GoogleSignInPlugin の初期化
dart
    plugin = GoogleSignInPlugin();
    await plugin?.init();

 
2. Google認証の更新を listenToUserDataEvents で監視
plugin?.userDataEvents が Stream<GoogleSignInUserData?>? 型になっている

dart
    // 認証情報の更新を監視
  Future<void> listenToUserDataEvents() async {
    plugin?.userDataEvents?.listen((userData) async {
        // 認証情報が更新されるとこの部分のコードが動く
    });
  }

 
3. google_sign_in_web が用意しているSignInボタンからGoogle認証

dart
    plubin?.renderButton()

 
4. listenToUserDataEvents がGoogle認証の更新を検知

 
5. listenToUserDataEvents の listen 内のコードが動いてFirebaseAuthにサインイン

dart
// FirebaseAuth にサインイン
      if (data.idToken != null) {
        final signInTokenData = await plugin?.getTokens(email: data.email);

        final auth = FirebaseAuth.instance;
        await auth.signInWithCredential(
          GoogleAuthProvider.credential(
            idToken: data.idToken,
            accessToken: signInTokenData?.accessToken,
          ),
        );

参考

https://github.com/flutter/flutter/issues/124297

Discussion