Flutter:GoogleService-Info.plist file not foundとなり、iOSでGoogleサインインできない
結論:Firebaseから最新の「GoogleService-Info.plist」をダウンロードして差し替える
2023/5/15 Flutter エラー・バグ日記
Googleサインインの機能を導入したところ、Androidではサインインできるのに、なぜかiOSでサインインしようとすると、以下のエラーが出てサインインできない状況に陥った。
PlatformException(missing-config, GoogleService-Info.plist file not found and clientId was not provided programmatically., null, null)
「GoogleService-Info.plist」が見つからない、ということのようだが、きちんとFirebaseの管理画面からダウンロードして、「ios/Runner」の下に、Xcodeを用いて配置していた。
自分で整理した下記記事に従って設定すれば、いつも問題なく動作していたのだが。。
「GoogleSignIn」クラスの「clientId」を設定すると解消する
ネット上を調べると、以下に同じエラー報告があった。
これによると、「GoogleSignIn」クラスのインスタンスを作る際、「clientId」のプロパティを以下のように設定する必要があるとの事。
// ↓このGoogleSignInのインスタンスを使って、googleSignInO.signIn() のようなサインインメソッドを作る googleSignInO = GoogleSignIn( clientId: DefaultFirebaseOptions.currentPlatform.iosClientId, // ←これを追加(「firebase_options.dart」のインポートが必要) scopes: [ driveO.DriveApi.driveAppdataScope, // 必要な権限(スコープ)を記載する部分 ]); )
「DefaultFirebaseOptions」を使うには、「firebase_options.dart」(Firebase導入時に自動作成されるファイル)のインポートが必要になる。
確かに「clientId」を追記したところ、問題なくiOSでもGoogleサインインできるようになった。
iOS用のクライアントIDを設定してしまうと、今度はAndroidでサインインできなくなるのではないか、と思ったが、なぜかAndroidでも引き続きサインインできた。
「google_sign_in」パッケージのソースコード中の「clientId」部分の説明を見ると、下記記述があり、どうやらAndroidではサポートされていないプロパティらしい。
Client ID being used to connect to google sign-in.
This option is not supported on all platforms (e.g. Android). It is optional if file-based configuration is used.
The value specified here has precedence over a value from a configuration file.
Google サインインへの接続に使用されるクライアント ID。
このオプションは、すべてのプラットフォーム (Android など) でサポートされているわけではありません。 ファイルベースの構成を使用する場合はオプションです。
ここで指定した値は、構成ファイルの値よりも優先されます。 ※Google翻訳結果
そのため、Androidの場合は「clientId」が読み飛ばされるので、追記しても影響がない模様。。
「GoogleService-Info.plist」に「ANDROID_CLIENT_ID」が必要だった?
確かに「clientId」を設定することで解消されたが、他に作成したアプリでは「clientId」の設定をしなくても、iOSでGoogleサインインできていた。
できれば、余計なプロパティは設定したくない。。
そこで、改めて設定系を確認してみる。
まず「Info.plist」に「CFBundleTypeRole」を設定する部分は適切になされていた。
「REVERSED_CLIENT_ID」を「GoogleService-Info.plist」から転記する部分も、問題なく完了していた。
※以上は、こちらの「google_sign_in」パッケージの説明に従った設定。
次に、Firebaseからダウンロードした「GoogleService-Info.plist」に問題があるかもしれないと考え、再度ダウンロードして中身を比較してみた。
すると、再ダウンロードした方には、下記のように、「ANDROID_CLIENT_ID」が新しく追加されていた。
<key>ANDROID_CLIENT_ID</key> <string>############.apps.googleusercontent.com</string>
iOS用の設定ファイルなのに、なぜ「ANDROID_CLIENT_ID」?と思ったが、とにかくファイルが更新されているようなので、古い「GoogleService-Info.plist」を削除して、新しいファイルに差し替えた。
すると、「clientId」プロパティを設定せずとも、問題なくiOSでもサインインできるようになった。
「ANDROID_CLIENT_ID」は両OSでサインインするために必要らしい
なぜiOS用の設定ファイル(GoogleService-Info.plist)に、「ANDROID_CLIENT_ID」が必要なのか、疑問だったので、ネット上を調べたが、情報を見つけられなかった。
そこで、ChatGPTに聞いてみると、下記のような回答だった。
- 「GoogleService-info.plist」ファイル内の「ANDROID_CLIENT_ID」は、Firebaseの設定ファイルがiOSとAndroidの両方のプラットフォームで使用されることを考慮して存在しており、これは、iOSアプリとAndroidアプリが同じFirebaseプロジェクトに関連付けられている場合に役立つ。
- 具体的には、Firebase AuthenticationやFirebase Dynamic Linksなどの一部のFirebaseサービスは、iOSとAndroidの両方で利用できる機能を提供している。これらの機能を使用する場合、iOSアプリとAndroidアプリの間でデータを共有する必要がある。
- 「ANDROID_CLIENT_ID」は、AndroidアプリがFirebase Authenticationを使用してGoogleアカウントでログインする際に必要なクライアントIDである。これにより、ユーザーがAndroidアプリでログインした後、同じアカウントでiOSアプリにも自動的にログインすることができる。このように、同じFirebaseプロジェクトを使用する複数のプラットフォーム間でのユーザーのシームレスな認証を実現することができる。
なるほど、、確かにテストした時は、AndroidとiOSで、同じGoogleアカウントでサインインしようとしていたので、この設定が必要だったのかもしれない。。
一方で、Firebase Authentication(「firebase_auth」パッケージ)を使用せずに、Googleサインインする方法を採用していたので、この部分はよく理解できず。。
ソースの情報を見つけられないので、確証は得られないが、ともかく、今後も「GoogleService-info.plist」が更新されていないか、Firebase上でチェックする必要があると認識。
\一般的なエラー対処法をまとめた記事はこちら/
リリースしたアプリ(全てFlutterで開発)
個人アプリ開発で役立ったもの
おすすめの学習教材
\超初心者向けでオススメな元Udemyの講座/
\キャンペーン時を狙えば安価で網羅的な内容が学べる(日本語訳あり)/
\Gitの基礎について無料で学べる/
おすすめの学習書籍
\実用的。image_pickerに関してかなり助けられた/
\Dartの基礎文法を素早くインプットできる/
Dart入門 - Dartの要点をつかむためのクイックツアー