どうも、Flutterでアプリを作ってみようと試行錯誤中のたくチャレ(@takuchalle)です。

Firebaeの機能を色々試していて、Firebase Authでログインした状態でFirebase Storageに画像をアップロードしようと思った時にハマった時のメモです。

AuthStorageもちゃんと設定しているはずなのに、全然アップロードされない。Firebase Storageのルールでif request.auth != nullを外すとちゃんとアップロードされるから認証周りがうまくいってないと思うんだけどよくわからないっていう状況でした。

Firebase Auth のサンプル

Firebae AuthREADMEには次のように書いてあります。

final FirebaseAuth _auth = FirebaseAuth.instance;

たくチャレ「なるほど、シングルトンになってて、インスタンスを取ってくればいいんだな」

Firease Storage のサンプル

一方、Firebase StorageREADMEは全然情報がなかったので、exampleを見ると次のように書いてあります。

final FirebaseApp app = await FirebaseApp.configure(
	name: 'test',
	options: FirebaseOptions(
		googleAppID: Platform.isIOS
			? '1:159623150305:ios:4a213ef3dbd8997b'
			: '1:159623150305:android:ef48439a0cc0263d',
		gcmSenderID: '159623150305',
		apiKey: 'AIzaSyChk3KEG7QYrs4kQPLP1tjJNxBTbfCAdgg',
		projectID: 'flutter-firebase-plugins',
	),
final FirebaseStorage storage = FirebaseStorage(
	app: app, storageBucket: 'gs://flutter-firebase-plugins.appspot.com');
);

たくチャレ「なるほど、FirebasAppを設定して、FirebaseStorageを初期化するんだな」

組み合わせると

動かないわけですよ

色々考えて、検索して、SDK のコードを読んでやっとわかりました。

理由はFirebae AuthはデフォルトのFirebaeAppを使っていて、Firebase Storageは自分で設定したFirebaseAppを使ってるからでした。

つまり、Firebase AuthFirebaseAuth.fromApp(FirebaseApp app)で初期化するか、Firebase StorageFirebaseStorage.instanceでインスタンスをとるべきでした。 異なるFirebaeAppを参照してたから認証が通らずアップロードができないということでした。

デフォルトのFirebaseApp、つまりiPhoneだとGoogleServices-Info.plistに定義されている情報で初期化されたFirebaseAppを素直に使いましょう。次のように何も設定せずにインスタンスを取るだけです。

final FirebaseApp app = await FirebaseApp.instance;
final FirebaseAuth auth = FirebaseAuth.instance;
final FirebaseStorage storage = FirebaseStorage.instance;

もし、複数のFirebaeプロジェクトを一つのアプリで使いたくなった時にconfigureして使い分けしましょう。

まとめ

自分がちゃんとコードを見ずにコピペしてやろうと思ったから、ハマってしまいました…

同じリポジトリでサンプルを公開するなら書き方を統一してほしかったなあ。ただでされFlutter Firebaseのドキュメント少ないのに。 でも、これで内部の仕組みが少し理解できてよかったです!(無駄にポジティブ)

同じカテゴリの記事