Flutter for webでFirebase storageを使う際にfirebase_storageがweb未対応だったため、firebaseを用いて実装したら、storage().ref()
が上手くいかなかったので対応しました。
結論
ルートパスを参照する場合でも明示的に'/'
を渡すことで解決します。
🙅♂️:storage().ref()
🙆♂️:storage().ref('/')
環境
- Flutter 1.19.0-1.0.pre • channel dev
- Dart 2.9.0 (build 2.9.0-7.0.dev 092ed38a87)
- firebase: ^7.3.0
- (firebase_storage: ^3.1.6)
問題
ref()
を参照する際に、firebase_storageパッケージでは以下のように参照できます。
import 'package:firebase_storage/firebase_storage.dart';
void main() {
final storageReference = FirebaseStorage.instance.ref();
}
firebaseパッケージでも同様のことをすると例外が吐かれました。
import 'package:firebase/firebase.dart' as firebase;
void main() {
try {
final storageReference = firebase.storage().ref();
} catch(e,s) {
print(e); // => [object Object]
print(s); // => Non-error `[object Object]` thrown by JS does not have stack trace. Caught in Dart at: ...
}
}
解決法
firebaseパッケージを使う際は、ルートを参照する場合でも明示的に'/'
を渡しましょう。
import 'package:firebase/firebase.dart' as firebase;
void main() {
try {
final storageReference = firebase.storage().ref('/'); // 明示的にルートパスを指定
} catch(e,s) {
print(e);
print(s);
}
}
このref
の内部実装は以下のようになっており、ref()
と呼び出すとjsObject.ref(null)
が呼ばれてしまいます。
/// Returns a [StorageReference] for the given [path] in the default bucket.
StorageReference ref([String path]) =>
StorageReference.getInstance(jsObject.ref(path));
このjsObject.ref(path)
というのは以下のStorageJsImpl
のref
なので、dartでのfirebase.storage().ref()
はjsでのfirebase.storage().ref(null)
を呼んでいることになります。
@JS('Storage')
abstract class StorageJsImpl {
...
external ReferenceJsImpl ref([String path]);
...
}
ちなみにChromeのコンソールで確認してみると、firebase.storage().ref(null)
はエラーとなっているのがわかります。