0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Flutter web でFirebase&GoogleSignIn認証しようとしてハマった話(2.8以降は注意?)

Posted at

Flutterでwebアプリ開発を始めました。
以前にVue.jsを使ってFirebaseHostingを使ったWebアプリでFirebase&GoogleSignInでの認証を作っていて、「認証に簡単にできるんだ!」と感動した覚えがあったので、今回もサクッと認証機能を入れ込もうと思ったのですが、、、、思いの他はまったので、記録として残します。

最初に結論

  • Flutter2.8以降でFirebaseを使ったログイン方法が変わっているようです。(詳しくは理解していない)
  • このバージョン以前の実装方法はいろんな記事があり、そのまま実装で大丈夫そう。
  • 2.8以降?ではFirebaseAuth.signInWithPopup()を使うとうまくいく。(行った)

補足

  • この記事ではFirebaseの設定や、GCPの設定は記載していません。他参考サイトを貼っておきます。
  • 環境・パッケージのバージョンは最後に記載しています。

はまったコード

だいたい色んな参考サイトを見てみるとこんな感じで記載されていると思います。
Flutterを使ったAndroidアプリ、iOSアプリならこれで大丈夫な様子。

  Future<void> googleSignin() async {
    // Google認証の部分
    final GoogleSignIn _googleSignIn = GoogleSignIn(
      scopes: [
        'email',
        'https://www.googleapis.com/auth/contacts.readonly',
      ],
    );
    try {
      final GoogleSignInAccount? googleUser = await _google_signin.signIn();
    } catch (error) { print(error); }
    
    final GoogleSignInAuthentication? googleAuth =
        await googleUser?.authentication;

    // 🔥🔥🔥🔥🔥 クレデンシャルの取得 🔥🔥🔥🔥🔥
    final AuthCredential credential = GoogleAuthProvider.credential(
      idToken: googleAuth?.idToken,
      accessToken: googleAuth?.accessToken,
    );

    //  Firebase 認証 インスタンス生成
    final FirebaseAuth _fauth = FirebaseAuth.instance;
    // Google認証を通過した後、Firebase側にログイン 
    try {
      final UserCredential result =
          await _fauth.signInWithCredential(credential);
      user = result.user;
    
    // TODO:ログイン後画面にアカウントを引き継ぐ
    // ログイン後の画面遷移
      Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => NextView(), 
          ));
    } catch (e) {
      print(e);
    }
  }

このコードで散々試しましたが、、、🔥🔥🔥🔥🔥の部分で以下のエラーが出て、うまくいきませんでした。。。

はまったエラー
Error: Assertion failed:
file:///xxxx/flutter_dev/flutter/.pub-cache/hosted/pub.dartlang.org
/firebase_auth_platform_interface-6.2.5/lib/src/providers/google_auth.dart:43
:12
accessToken != null || idToken != null
"At least one of ID token and access token is required"
    at Object.throw_ [as throw] (http://localhost:7357/dart_sdk.js:5067:11)
    at Object.assertFailed (http://localhost:7357/dart_sdk.js:4992:15)
    at Function.credential
    (http://localhost:7357/packages/firebase_auth_platform_interface/src/type
    s.dart.lib.js:516:59)
    at main.xxxx.new.googleSignin
    (http://localhost:7357/packages/mappy/main.dart.lib.js:527:57)
    at googleSignin.next (<anonymous>)
    at http://localhost:7357/dart_sdk.js:40571:33
    at _RootZone.runUnary (http://localhost:7357/dart_sdk.js:40441:59)
    at _FutureListener.thenAwait.handleValue
    (http://localhost:7357/dart_sdk.js:35363:29)
    at handleValueCallback (http://localhost:7357/dart_sdk.js:35931:49)
    at Function._propagateToListeners
    (http://localhost:7357/dart_sdk.js:35969:17)
    at _Future.new.[_complete] (http://localhost:7357/dart_sdk.js:35809:25)
    at http://localhost:7357/dart_sdk.js:34915:30
    at internalCallback (http://localhost:7357/dart_sdk.js:26619:11)

なぜかはよくわかりませんでしたが、googleUser?.authenticationの結果は取得できているものの、
それを使った、GoogleAuthProvider.credential(xx)の結果はnullになっている。。。

うまく動いたコード

ちょーシンプルですが、いかでGoogle認証して、Firebase認証までしてくれます。

  Future<void> googleSignin() async {
    GoogleAuthProvider authProvider = GoogleAuthProvider();
    try {
      final UserCredential userCredential =
          await _fauth.signInWithPopup(authProvider);

      user = userCredential.user;
    // TODO:ログイン後画面にアカウントを引き継ぐ
    // ログイン後の画面遷移
      Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => NextView(), 
          ));
    } catch (e) {
      print(e);
    }

その他にハマった対策メモ

ローカルテストでGoogle認証を使うには、ポートを指定して起動する必要がある

ポート指定での起動方法

$ flutter run -d chrome --web-hostname localhost --web-port 7357

「GCP -> APIとサービス -> 認証情報」で以下のように設定してあげる。
ウェブ_アプリケーション_のクライアント_ID_–API_とサービス–kenymap2022–_Google_Cloud_Platform.png

認証のリダイレクト先にFirebaseの登録が必要

同じく、「GCP -> APIとサービス -> 認証情報」で以下のように設定してあげる。
ウェブ_アプリケーション_のクライアント_ID_–API_とサービス–kenymap2022–_Google_Cloud_Platform.png
この部分に下のID部分を登録してあげる。
Banners_and_Alerts_と_kenymap2022_-プロジェクトの設定-_Firebase_コンソール.png

参考サイト

環境

doctor

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.10.3, on Mac OS X 10.14.6 18G103 darwin-x64, locale ja-JP)
[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[✗] Xcode - develop for iOS and macOS
    ✗ Xcode installation is incomplete; a full installation is necessary for iOS development.
      Download at: https://developer.apple.com/xcode/download/
      Or install Xcode via the App Store.
      Once installed, run:
        sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
        sudo xcodebuild -runFirstLaunch
    ✗ CocoaPods not installed.
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the
        Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
[✓] Chrome - develop for the web
[!] Android Studio (not installed)
[✓] VS Code (version 1.66.2)
[✓] Connected device (1 available)
[✓] HTTP Host Availability

! Doctor found issues in 3 categories.

パッケージバージョン

$ flutter pub outdated
Showing outdated packages.
[*] indicates versions that are not the latest available.

Package Name              Current  Upgradable  Resolvable  Latest  

direct dependencies: all up-to-date.

dev_dependencies:        
firebase_core             *1.15.0  1.16.0      1.16.0      1.16.0  
flutter_lints             *1.0.4   *1.0.4      *1.0.4      2.0.1   
google_maps_flutter       *2.1.3   2.1.4       2.1.4       2.1.4   

transitive dependencies: 
characters                *1.2.0   *1.2.0      *1.2.0      1.2.1   
collection                *1.15.0  *1.15.0     *1.15.0     1.16.0  
material_color_utilities  *0.1.3   *0.1.3      *0.1.3      0.1.5   
vector_math               *2.1.1   *2.1.1      *2.1.1      2.1.2   

transitive dev_dependencies:
async                     *2.8.2   *2.8.2      *2.8.2      2.9.0   
fake_async                *1.2.0   *1.2.0      *1.2.0      1.3.0   
google_maps               *5.3.0   *5.3.0      *5.3.0      6.1.0   
js                        *0.6.3   *0.6.3      *0.6.3      0.6.4   
lints                     *1.0.1   *1.0.1      *1.0.1      2.0.0   
path                      *1.8.0   *1.8.0      *1.8.0      1.8.1   
source_span               *1.8.1   *1.8.1      *1.8.1      1.9.0   
test_api                  *0.4.8   *0.4.8      *0.4.8      0.4.9   

2 upgradable dependencies are locked (in pubspec.lock) to older versions.
To update these dependencies, use `flutter pub upgrade`.
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?