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)はエラーとなっているのがわかります。
