Flutter google_sign_in 升級到 7.x


#flutter#google_sign_in

為什麼要升級?


  1. 6.x 基於舊的 Google Sign-In SDK,已經被官方標註 deprecated
  2. 7.x 支援新的 OpenID Connect 流程,統一各平台 API
  3. 新增支援 nonce 參數,更安全的 ID token 驗證

差異


功能 6.x 7.x
GoogleSignIn 建構 GoogleSignIn(scopes: ['email']) GoogleSignIn.instance.initialize(serverClientId: ...)
signIn await _googleSignIn.signIn() await GoogleSignIn.instance.authenticate(scopeHint: ['email'], nonce: ...)
silent signIn signInSilently() attemptLightweightAuthentication()
access token 直接在 authentication 透過 authorizationClient.authorizationForScopes()

修改程式碼


6.x 寫法


try {
  final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['email']);

  final GoogleSignInAccount? account = await _googleSignIn.signIn();
  if (account != null) {
    return GoogleUserDataModel(
      account.id,
      (await account.authentication).idToken ?? '',
      (await account.authentication).accessToken ?? '',
      account.displayName ?? '',
      account.email,
      account.photoUrl,
    );
  }
} catch (error) {
  return null;
}
return null;

7.x 寫法


try {
  await GoogleSignIn.instance.initialize(
    serverClientId: '<google-services.json → oauth_client → client_type: 3 → client_id>',
    nonce: '<optional, provide your own nonce value if required>',
  );

  GoogleSignInAccount account = await GoogleSignIn.instance.authenticate(scopeHint: ['email']);

  GoogleSignInClientAuthorization? tokenInfo = await account.authorizationClient.authorizationForScopes(['email']);

  return GoogleUserDataModel(
    account.id,
    account.authentication.idToken ?? '',
    tokenInfo?.accessToken ?? '',
    account.displayName ?? '',
    account.email,
    account.photoUrl,
  );
} catch (error) {
  return null;
}

遇到問題


iOS 滿順利的,只要 pod update 一下就好

pod update GoogleSignIn AppAuth

Android 就花了點時間,選完帳號無反應,出現 Exception: GoogleSignInExceptionCode.canceled

I/flutter (14536): GoogleSignInException(code GoogleSignInExceptionCode.canceled, activity is cancelled by the user., null)

出現這個 Exception 這一定是使用者取消,沒設定好也可能會出現

Some configuration errors will cause the underlying Android CredentialManager SDK to return a “canceled” error in this flow, and unfortunately the google_sign_in plugin has no way to distinguish this case from the user canceling sign-in, so cannot return a more accurate error message.

有幾種可能:

  • Firebase SHA-1 指紋設定錯誤,Debug 跟 Release 的都要設定。
  • serverClientId 設定錯誤,要拿 google-services.json 檔案中 oauth_clientclient_type 為 3 的 client_id
  • Android package name 錯誤。

Your google-services.json contains a web OAuth client, which should be an oauth_client entry with client_type: 3. This should have been created automatically when enabling Google Sign In using the Firebase console, but if not (or if it was later removed), add a web app to the project and then re-download google-services.json.


參考:
https://github.com/flutter/packages/blob/main/packages/google_sign_in/google_sign_in/MIGRATION.md
https://pub.dev/packages/google_sign_in_android/versions/7.0.3#troubleshooting