在 Flutter 中访问 Firebase 存储

Posted

技术标签:

【中文标题】在 Flutter 中访问 Firebase 存储【英文标题】:Access to Firebase Storage in Flutter 【发布时间】:2018-11-27 01:06:10 【问题描述】:

我对 Flutter 还很陌生,之前从未使用过 Firebase,因此如果有明显的解决方案,我深表歉意。

我正在开发一个 Flutter 应用程序,该应用程序涉及记录表单提交并将它们提交到一个中心位置。

Firebase 存储似乎很合适,因为据我了解,该应用可以将文件上传到云存储桶,然后可以通过 Firebase 控制台访问它们。如果我错了纠正我。

所以我找到了 Flutter 的这个模块;https://pub.dartlang.org/packages/firebase_storage

我以示例代码为基础。

在我调用的代码开始时;

final FirebaseApp app = await FirebaseApp.configure(
  name: 'test',
  options: new FirebaseOptions(
    googleAppID: Platform.isios
        ? 'ios app id'
        : 'android app ID',
    gcmSenderID: 'project number code',
    apiKey: 'web api key from the firebase console',
    projectID: 'project ID',
  ),
);
storage = new FirebaseStorage(
    app: app, storageBucket: 'address to data bucket');

然后上传我尝试过的文件;

final StorageReference ref =
storage.ref().child('uploads').child(filename);
final StorageUploadTask uploadTask = ref.putFile(
  file,
  new StorageMetadata(
    contentLanguage: 'en',
    customMetadata: <String, String>'activity': 'submission',
  ),
);


final Uri downloadUrl = (await uploadTask.future).downloadUrl;

final http.Response downloadData = await http.get(downloadUrl);
final String name = await ref.getName();
final String bucket = await ref.getBucket();
final String path = await ref.getPath();


return downloadData.statusCode >= 200 && 299 >= downloadData.statusCode;

在 Firebase 控制台中,我创建了 Uploads 文件夹,我认为其他所有设置都正确。

我的 Firebase 存储访问规则如下所示;

service firebase.storage 
  match /b/bucket/o 
    match /allPaths=** 
      allow read, write: if request.auth != null;
    
  

我的问题是当我尝试上传文件时出现以下错误;

W/DynamiteModule(25832): Local module descriptor class for com.google.android.gms.firebasestorage not found.
I/DynamiteModule(25832): Considering local module com.google.android.gms.firebasestorage:0 and remote module com.google.android.gms.firebasestorage:6
I/DynamiteModule(25832): Selected remote version of com.google.android.gms.firebasestorage, version >= 6
W/System  (25832): ClassLoader referenced unknown path: /data/data/com.google.android.gms/app_chimera/m/00000040/n/armeabi-v7a
W/System  (25832): ClassLoader referenced unknown path: /data/data/com.google.android.gms/app_chimera/m/00000040/n/armeabi
E/StorageUtil(25832): error getting token java.util.concurrent.ExecutionException: com.google.firebase.internal.api.FirebaseNoSignedInUserException: Please sign in before trying to get a token.
W/NetworkRequest(25832): no auth token for request
E/StorageException(25832): StorageException has occurred.
E/StorageException(25832): User does not have permission to access this object.
E/StorageException(25832):  Code: -13021 HttpResult: 403
E/StorageException(25832): The server has terminated the upload session
E/StorageException(25832): java.io.IOException: The server has terminated the upload session
E/StorageException(25832):  at com.google.firebase.storage.UploadTask.zzs(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.UploadTask.zzr(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.UploadTask.run(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.StorageTask.zzl(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.zzq.run(Unknown Source)
E/StorageException(25832):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
E/StorageException(25832):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
E/StorageException(25832):  at java.lang.Thread.run(Thread.java:818)
E/StorageException(25832): Caused by: java.io.IOException:   "error":     "code": 403,    "message": "Permission denied. Could not perform this operation"  
E/StorageException(25832):  at bha.a(:com.google.android.gms.dynamite_dynamitemodulesc@12685022@12.6.85 (040308-197041431):147)
E/StorageException(25832):  at bha.a(:com.google.android.gms.dynamite_dynamitemodulesc@12685022@12.6.85 (040308-197041431):119)
E/StorageException(25832):  at bgu.onTransact(:com.google.android.gms.dynamite_dynamitemodulesc@12685022@12.6.85 (040308-197041431):7)
E/StorageException(25832):  at android.os.Binder.transact(Binder.java:387)
E/StorageException(25832):  at com.google.android.gms.internal.firebase_storage.zza.transactAndReadExceptionReturnVoid(Unknown Source)
E/StorageException(25832):  at com.google.android.gms.internal.firebase_storage.zzm.zzf(Unknown Source)
E/StorageException(25832):  at com.google.android.gms.internal.firebase_storage.zzq.zza(Unknown Source)
E/StorageException(25832):  at com.google.android.gms.internal.firebase_storage.zzf.zza(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.UploadTask.zzc(Unknown Source)
E/StorageException(25832):  ... 6 more
E/StorageException(25832): StorageException has occurred.
E/StorageException(25832): User does not have permission to access this object.
E/StorageException(25832):  Code: -13021 HttpResult: 403
E/StorageException(25832): The server has terminated the upload session
E/StorageException(25832): java.io.IOException: The server has terminated the upload session
E/StorageException(25832):  at com.google.firebase.storage.UploadTask.zzs(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.UploadTask.zzr(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.UploadTask.run(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.StorageTask.zzl(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.zzq.run(Unknown Source)
E/StorageException(25832):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
E/StorageException(25832):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
E/StorageException(25832):  at java.lang.Thread.run(Thread.java:818)
E/StorageException(25832): Caused by: java.io.IOException:   "error":     "code": 403,    "message": "Permission denied. Could not perform this operation"  
E/StorageException(25832):  at bha.a(:com.google.android.gms.dynamite_dynamitemodulesc@12685022@12.6.85 (040308-197041431):147)
E/StorageException(25832):  at bha.a(:com.google.android.gms.dynamite_dynamitemodulesc@12685022@12.6.85 (040308-197041431):119)
E/StorageException(25832):  at bgu.onTransact(:com.google.android.gms.dynamite_dynamitemodulesc@12685022@12.6.85 (040308-197041431):7)
E/StorageException(25832):  at android.os.Binder.transact(Binder.java:387)
E/StorageException(25832):  at com.google.android.gms.internal.firebase_storage.zza.transactAndReadExceptionReturnVoid(Unknown Source)
E/StorageException(25832):  at com.google.android.gms.internal.firebase_storage.zzm.zzf(Unknown Source)
E/StorageException(25832):  at com.google.android.gms.internal.firebase_storage.zzq.zza(Unknown Source)
E/StorageException(25832):  at com.google.android.gms.internal.firebase_storage.zzf.zza(Unknown Source)
E/StorageException(25832):  at com.google.firebase.storage.UploadTask.zzc(Unknown Source)
E/StorageException(25832):  ... 6 more

是否可以使用应用帐户(服务帐户)登录,以便个人用户无需登录?

我在这里做错了什么?

【问题讨论】:

我猜你缺少的是pub.dartlang.org/packages/firebase_auth。如果您在 Android 模拟器中运行,请确保它是安装了 Play 商店的模拟器。 “Play 商店”应为“Google Play 服务” 是的,我应该提到我已经添加了这个包以查看它是否需要,在此之前错误包括在其他消息之前对它的引用 【参考方案1】:

引用来自您的StorageException

用户无权访问此对象。

这是您所期望的,因为您的规则声明如下:

allow read, write: if request.auth != null;

Firebase 使用身份验证。

两个选项可以解决这个问题:

您可以通过 Firebase 使用 firebase_auth 插件

验证您的用户>

或者您可以通过将规则更改为 allow read, write;

来公开您的文件

Storage Rules documentation 包含有关集成 Firebase 身份验证的信息。

【讨论】:

是的,这就是我的想法,但是即使我将存储访问权限设置为公共,我也会出现同样的错误。更新访问规则有延迟吗? @peopletookallthegoodnames 我不这么认为。你可能遗漏了什么。 是的,规则的传播似乎略有延迟,所以当我稍后再次尝试公共访问时,一切都按预期工作!谢谢

以上是关于在 Flutter 中访问 Firebase 存储的主要内容,如果未能解决你的问题,请参考以下文章

从 Flutter Web 应用程序发送 Firebase 存储授权作为 url 参数

Flutter - 在 Firebase 中存储小部件?

如何在 Flutter 中等待文件上传到 Firebase 存储?

Flutter / Dart / Firebase - 流返回空列表

Flutter - 将图像上传到 Firebase 存储

如何在 Flutter 中从 firebase 存储读取和写入文本文件?