在Flutter中从Firebase Storage获取下载URL

25

我目前正在探索Flutter,我发现Flutter中有一个官方的Firebase Storage插件firebase_storage。我有一个类似这样的存储引用:

final StorageReference ref = FirebaseStorage.instance.ref().child("default.png");

但是没有一种方法可以从那个 StorageReference 获取下载 URL。


1
你怎么上传图片?我还没有找到一个简单的方法从StorageReference中获取下载路径。我认为Firebase Storage插件仍然缺少一些功能,无法像https://firebase.google.com/docs/storage/web/download-files中所示那样做某些事情。 - Günter Zöchbauer
正如Gunter所提到的,没有办法在上传图像之前获取下载路径。 - Rosário Pereira Fernandes
为什么之前你需要它? - Razvan Cristian Lung
我手动从Firebase控制台上传了图像。只需要包装本地Firebase存储库到Flutter平台通道的几行代码。好吧,我通过扩展当前插件来完成了我的任务。 - Putra Ardiansyah
这个还没有被实现,但我们正在努力。同时,欢迎提交拉取请求。 - Collin Jackson
显示剩余2条评论
18个回答

32
如果上述解决方案不起作用,请尝试以下方法:
Future<String> uploadImage(var imageFile ) async {
    StorageReference ref = storage.ref().child("/photo.jpg");
    StorageUploadTask uploadTask = ref.putFile(imageFile);

    var dowurl = await (await uploadTask.onComplete).ref.getDownloadURL();
    url = dowurl.toString();

    return url; 
}

现在这才是正确的做法。谢谢,伙计,我花了两个小时来搞清楚这是什么鬼! - egorikem
3
以上方法已被弃用,请查看此答案:https://dev59.com/tlIG5IYBdhLWcg3whQSH#64764390 - Peter Haddad
请问您能否查看我的问题:https://stackoverflow.com/questions/68351097/reading-firebase-storage-image-security-rules - Noobdeveloper

11

使用以下格式的URL:

printUrl() async {
    StorageReference ref = 
        FirebaseStorage.instance.ref().child("images/sky.jpg");
    String url = (await ref.getDownloadURL()).toString();
    print(url);
}

7

最新版本firebase_storage: ^5.0.1应该采用以下方式:

Reference reference = FirebaseStorage.instance.ref().child("SupportChatImages").child(fileName);

    UploadTask uploadTask =  reference.putFile(imageFile);

    uploadTask.whenComplete(() async{

      try{
        imageUrl = await reference.getDownloadURL();
      }catch(onError){
        print("Error");
      }

      print(imageUrl);

    });

1
非常感谢您的回答! - Krishna Shetty
你好,这个代码可以用于一个文件,但是我不确定如何让它适用于文件列表。我需要做类似这样的事情: Future<List<String>> _uploadFiles(List<PickedFile> files) async { 在之前的版本中,由于for循环内部有"await",所以使用StorageTaskSnapshot snapshot = await uploadTask.onComplete;是可以正常工作的。 - Ishaan Puniani
这是完美的解决方案。 - Dario Brux

6

我已经实现了一种方法,可以将您的图像保存为带有时间戳的文件,并获得可下载的URL。

Future<String>photoOption() async {
    try {
        DateTime now = new DateTime.now();
        var datestamp = new DateFormat("yyyyMMdd'T'HHmmss");
        String currentdate = datestamp.format(now);
        File imageFile = await ImagePicker.pickImage();


        StorageReference ref = FirebaseStorage.instance
            .ref()
            .child("images")
            .child("$currentdate.jpg");
        StorageUploadTask uploadTask = ref.putFile(imageFile);

        Uri downloadUrl = (await uploadTask.future).downloadUrl;
        addUser.downloadablelink = downloadUrl.toString();

        downloadableUrl = downloadUrl.toString();

        print(downloadableUrl);

    } catch (error) {
        print(error);
    }

    return downloadableUrl;
}

如果我想从一个文件夹中下载所有文件,我只需要提供文件夹名称吗? - grepLines
https://dev59.com/11oU5IYBdhLWcg3wjHdL - siva kumar
2
put 已被弃用,请使用 putFile - nonybrighto
1
类'StorageUploadTask'没有定义'future'获取器。 - Midhilaj

5

对于 firebase_storage: ^10.0.1:

以下是获取已上传图像URL的代码:

uploadImagetFirebase(String imagePath) async {
 await FirebaseStorage.instance
  .ref(imagePath)
  .putFile(File(imagePath))
  .then((taskSnapshot) {
print("task done");

// download url when it is uploaded
if (taskSnapshot.state == TaskState.success) {
  FirebaseStorage.instance
      .ref(imagePath)
      .getDownloadURL()
      .then((url) {
    print("Here is the URL of Image $url");
    return url;
  }).catchError((onError) {
    print("Got Error $onError");
  });
}
});
}

1
谢谢您提供最新版本的答案,我一直在寻找这样的东西! - Nicolas Le Bot

3
Future<String> urlDownload(file) async {
var uuid = Uuid().v1();
StorageReference ref =
    FirebaseStorage.instance.ref().child("post_$uuid.jpg");
StorageUploadTask uploadTask = ref.putFile(file);

String downloadUrl =
    await (await uploadTask.onComplete).ref.getDownloadURL();
return downloadUrl;}

4
请考虑添加文字来解释答案中的代码。 - user11563547

1

试试这个

 Future<String> downloadFromFirebase() async {
  // Create reference
    StorageReference ref = FirebaseStorage.instance.ref().child("default.png");
    String _myUrl = await ref.getDownloadURL();
    return _myUrl.toString();
}

1
我尝试了很多方法,经过多次尝试,这个方法对我有效,因为Firebase Storage删除了旧的方法。如果有人遇到404对象未找到的错误,则下面的代码也可以解决该问题。
Future<String> uploadSingleImage(File file) async {
    //Set File Name
    String fileName = DateTime.now().millisecondsSinceEpoch.toString() +
        AuthRepository.getUser().uid +
        '.jpg';
    
    //Create Reference
    Reference reference = FirebaseStorage.instance
        .ref()
        .child('Single Post Images')
        .child(fileName);

    //Now We have to check the status of UploadTask
    UploadTask uploadTask = reference.putFile(file);
    
    String url;
    await uploadTask.whenComplete(() async {
      url = await uploadTask.snapshot.ref.getDownloadURL();
    });
   
    return url;
  }

1
他是我的解决方案:
StorageReference storageReference = FirebaseStorage.instance.ref().child("myfile"); 
StorageUploadTask uploadTask = storageReference.putFile(file);
uploadTask.onComplete.then((s){ 
   s.ref.getDownloadURL(); 
});

1
我的解决方案
Future mainprofile(File image) async {
    try {
      DateTime now = new DateTime.now();
      var datestamp = new DateFormat("yyyyMMdd'T'HHmmss");
      String currentdate = datestamp.format(now);
      _firebaseStorageRef = FirebaseStorage.instance
          .ref()
          .child(userRepository.uid)
          .child('main')
          .child("$currentdate.jpg");
      StorageUploadTask uploadTask = _firebaseStorageRef.putFile(image);
      uploadTask.onComplete.then((onValue) async {
        _mainurl = (await _firebaseStorageRef.getDownloadURL()).toString();
      });
    } catch (error) {
      print(error);
    }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接