如何从Firebase存储getDownloadURL获取URL

时间:2016-05-22 13:16:08

标签: java android firebase firebase-storage

我正试图获得"长期持续下载链接"到我们的Firebase存储桶中的文件。 我已将此权限更改为

service firebase.storage {
  match /b/project-xxx.appspot.com/o {
    match /{allPaths=**} {
      allow read, write;
    }
  }
}

我的javacode看起来像这样:

private String niceLink (String date){
    String link;
    // Points to the root reference
    StorageReference storageRef = FirebaseStorage.getInstance().getReference();
    StorageReference dateRef = storageRef.child("/" + date+ ".csv");
    link = dateRef.getDownloadUrl().toString();
    return link;
}

当我运行这个时,我得到了类似的uri链接 com.google.android.gms.tasks.zzh@xxx

问题1。我可以通过以下方式获得类似于以下内容的下载链接: https://firebasestorage.googleapis.com/v0/b/project-xxxx.appspot.com/o/20-5-2016.csv?alt=media&token=b5d45a7f-3ab7-4f9b-b661-3a2187adxxxx

当我尝试获取上面的链接时,我在返回之前更改了最后一行,如下所示:

private String niceLink (String date){
    String link;
    // Points to the root reference
    StorageReference storageRef = FirebaseStorage.getInstance().getReference();
    StorageReference dateRef = storageRef.child("/" + date+ ".csv");
    link = dateRef.getDownloadUrl().getResult().toString();
    return link;
}

但是当这样做时我得到403错误,并且应用程序崩溃了。 consol告诉我这是bc用户未登录/ auth。 "请在请求令牌"

之前登录

问题2. 如何解决此问题?

13 个答案:

答案 0 :(得分:14)

当您致电getDownloadUrl()时,该呼叫是异步的,您必须订阅成功回调才能获得结果:

// Calls the server to securely obtain an unguessable download Url
private void getUrlAsync (String date){
    // Points to the root reference
    StorageReference storageRef = FirebaseStorage.getInstance().getReference();
    StorageReference dateRef = storageRef.child("/" + date+ ".csv");
    dateRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>()
    {
        @Override
        public void onSuccess(Uri downloadUrl) 
        {                
           //do something with downloadurl
        } 
    });
}

这将返回一个公开的无法下载的网址。如果你刚刚上传了一个文件,那么这个公共网址将在上传的成功回调中(你上传后不需要再调用另一种异步方法)。

但是,如果你想要的只是参考的String表示,你只需拨打.toString()

// Returns a Uri of the form gs://bucket/path that can be used
// in future calls to getReferenceFromUrl to perform additional
// actions
private String niceRefLink (String date){
    // Points to the root reference
    StorageReference storageRef = FirebaseStorage.getInstance().getReference();
    StorageReference dateRef = storageRef.child("/" + date+ ".csv");
    return dateRef.toString();
}

答案 1 :(得分:1)

// Firebase简单且可工作的上载和下载。

@Override

**Code Format:**

Home Page : It has some Game
      

The router has 4 different subpages : 

Default Home Page that will show game, and the rest other pages are based on the dynamic link provided Ex: Page_1, Page_2, and Page_3. 

**What am I looking help or guidance?**

The suggestion I am looking is to avoid landing in home page (game landing page) when dynamic link is clicked from web url of the mobile.



void main() {

  runApp(new MaterialApp(
    title: 'Game Name',
    home: _MainScreen(),
    routes: <String, WidgetBuilder>{
      '/NSef': (BuildContext context) => new SocialAppsPage(
          "page-1-title",
          "page-1"),
      '/82AY': (BuildContext context) => new SocialAppsPage(
          "page-2-title",
          "page-2"),
      '/DW7Y': (BuildContext context) => new SocialAppsPage(
          "page-3-title",
          "page-3"),
      '/core': (BuildContext context) => new GameHomePage()
    },  ));
}

class _MainScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _MainScreenState();
}

class _MainScreenState extends State<_MainScreen>  with WidgetsBindingObserver {

  Timer _timerLink;


  @override
  BuildContext get context => super.context;

    @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _timerLink = new Timer(const Duration(milliseconds: 1), () {
        _retrieveDynamicLink();
      });
    }
  }

  Future<void> _retrieveDynamicLink() async {
    final PendingDynamicLinkData data =
    await FirebaseDynamicLinks.instance.retrieveDynamicLink();
    final Uri deepLink = data?.link;

    if (deepLink != null) {
      Navigator.pushNamed(context, deepLink.path);
    } else {
      Navigator.pushNamed(context, "/core");
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    if (_timerLink != null) {
      _timerLink.cancel();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return (new MaterialApp(
      title: 'Game Name',
      home: Center(
        child: CircularProgressIndicator(),
      ),
      navigatorObservers: <NavigatorObserver>[observer],
      routes: <String, WidgetBuilder>{
        '/NSef': (BuildContext context) => new SocialAppsPage(
            "page-1-title",
            "Page-1"),
        '/82AY': (BuildContext context) => new SocialAppsPage(
            "page-2-title",
            "Page-2"),
        '/DW7Y': (BuildContext context) => new SocialAppsPage(
            "page-3-title",
            "page-3"),
        '/core': (BuildContext context) => new GameHomePage()
      },
    ));
  }
}

Any help or suggestions is appreciated.
Thanks!

答案 2 :(得分:0)

StorageReference mStorageRef = FirebaseStorage.getInstance().getReference();

final   StorageReference fileupload=mStorageRef.child("Photos").child(fileUri.getLastPathSegment());
UploadTask uploadTask = fileupload.putFile(fileUri);

Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
    @Override
    public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
        if (!task.isSuccessful()) {
            throw task.getException();
        }
        return ref.getDownloadUrl();

    }
    }).addOnCompleteListener(new OnCompleteListener<Uri>() {
        @Override
        public void onComplete(@NonNull Task<Uri> task) {
            if (task.isSuccessful()) {
                Uri downloadUri = task.getResult();
                Picasso.get().load(downloadUri.toString()).into(image);

            } else {
                 // Handle failures
            }
       }
});

答案 3 :(得分:0)

我在这里同时上传并获取图片网址...

           final StorageReference profileImageRef = FirebaseStorage.getInstance().getReference("profilepics/" + System.currentTimeMillis() + ".jpg");

            if (uriProfileImage != null) {

            profileImageRef.putFile(uriProfileImage)
                        .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                            @Override
                            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                               // profileImageUrl taskSnapshot.getDownloadUrl().toString(); //this is depreciated

                          //this is the new way to do it
                   profileImageRef.getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
                                    @Override
                                    public void onComplete(@NonNull Task<Uri> task) {
                                       String profileImageUrl=task.getResult().toString();
                                        Log.i("URL",profileImageUrl);
                                    }
                                });
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                progressBar.setVisibility(View.GONE);
                                Toast.makeText(ProfileActivity.this, "aaa "+e.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        });
            }

答案 4 :(得分:0)

Clean And Simple
private void putImageInStorage(StorageReference storageReference, Uri uri, final String key) {
        storageReference.putFile(uri).addOnCompleteListener(MainActivity.this,
                new OnCompleteListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                        if (task.isSuccessful()) {
                            task.getResult().getMetadata().getReference().getDownloadUrl()
                                    .addOnCompleteListener(MainActivity.this, 
                                            new OnCompleteListener<Uri>() {
                                @Override
                                public void onComplete(@NonNull Task<Uri> task) {
                                    if (task.isSuccessful()) {
                                        FriendlyMessage friendlyMessage =
                                                new FriendlyMessage(null, mUsername, mPhotoUrl,
                                                        task.getResult().toString());
                                        mFirebaseDatabaseReference.child(MESSAGES_CHILD).child(key)
                                                .setValue(friendlyMessage);
                                    }
                                }
                            });
                        } else {
                            Log.w(TAG, "Image upload task was not successful.",
                                    task.getException());
                        }
                    }
                });
    }

答案 5 :(得分:0)

在大于11.0.5的Firebase版本中删除了getDownloadUrl方法 我建议使用仍使用此方法的版本11.0.2。

答案 6 :(得分:0)

对我来说,我在Kotlin中编写了代码,并且遇到了相同的错误“ getDownload()”。这是对我有用的依赖项以及Kotlin代码。

implementation 'com.google.firebase:firebase-storage:18.1.0' Firebase存储依赖项

这是我添加的内容,并且在Kotlin中对我有用。 Storage()会先于Download()

profileImageUri = taskSnapshot.storage.downloadUrl.toString()

答案 7 :(得分:0)

现在,新的Firebase更新中不建议使用getDownloadUrl方法。而是使用以下方法。 taskSnapshot.getMetadata()。getReference()。getDownloadUrl()。toString()

答案 8 :(得分:0)

将收到的 URI 更改为 URL

 val urlTask = uploadTask.continueWith { task ->
            if (!task.isSuccessful) {
                task.exception?.let {
                    throw it
                }
            }


            spcaeRef.downloadUrl
        }.addOnCompleteListener { task ->
            if (task.isSuccessful) {

                val downloadUri = task.result

                //URL
                val url = downloadUri!!.result

            } else {
                //handle failure here
            }
        }

答案 9 :(得分:0)

您可以将图像上传到Firestore并获取其下载URL,如下所示:

  Future<String> uploadPic(File _image) async {

    String fileName = basename(_image.path);
    StorageReference firebaseStorageRef = FirebaseStorage.instance.ref().child(fileName);
    StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
    var downloadURL = await(await uploadTask.onComplete).ref.getDownloadURL();
    var url =downloadURL.toString();

   return url;

  }

答案 10 :(得分:0)

答案 11 :(得分:0)

您也可以在最新的 Firebase_storage 版本 nullsafe 中执行以下操作,

//Import
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;

Future<void> _downloadLink(firebase_storage.Reference ref) async {
    //Getting link make sure call await to make sure this function returned a value
    final link = await ref.getDownloadURL();

    await Clipboard.setData(ClipboardData(
      text: link,
    ));

    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text(
          'Success!\n Copied download URL to Clipboard!',
        ),
      ),
    );
  }

答案 12 :(得分:-1)

 private void getDownloadUrl(){
        FirebaseStorage storage     = FirebaseStorage.getInstance();
        StorageReference storageRef = storage.getReference();
        StorageReference imageRef   = storageRef.child("image.jpg");
        imageRef.getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
            @Override
            public void onComplete(@NonNull Task<Uri> task) {
                String profileimageurl =task.getResult().toString();
                Log.e("URL",profileimageurl);
                ShowPathTextView.setText(profileimageurl);
            }
        });
    }