How to Store "direct link" to an image using Firebase Storage
Asked Answered
U

9

34

I need to access an image stored on Firebase Storage by a direct link, eg

http://myfirebasehost.com/storage/imgIwant.png

For all I know, it can only this type of URL using the protocol gs://, however, it is not accessible by link, only in the SDK api.

I need a solution exactly as described above using the Firebase platform, if not possible, accept other suggestions.

My code has constants that are links to images. It turns out that if I want to update this picture, I have to make a new deployment. Instead I want to update the image at the same URL. It would be impossible to do this with the firebase (to my knowledge) because the URL provided by Storage is not accessible by link.

Another alternative might be to convert an image to base64 and stored in the database, but would be very extensive and impractical.

Unionize answered 5/8, 2016 at 1:17 Comment(2)
You seem to have a problem getting your code to work. The best way to get help with that on Stack Overflow is to reproduce the problem in a minimal amount of code and post that code here.Rochelrochell
Maybe this can help you - #41424390Lushy
D
26

How to translate your gs storage location to a direct url by example:

gs://nobs-f32f2.appspot.com/profile/1s_by_wlop-dc1sdan.jpg

becomes

https://firebasestorage.googleapis.com/v0/b/nobs-f32f2.appspot.com/o/profile%2F1s_by_wlop-dc1sdan.jpg?alt=media

1st be sure to URL escape your blob path. For example, swap forward slashes (/) for %2F and spaces () for %20.

2nd be sure you've open read access where needed. Here is an open rule to get moving:

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read: if true;
      allow write: if request.auth != null;
    }
  }
}
Dincolo answered 19/5, 2018 at 19:13 Comment(4)
I didn't think the URL would work when missing the "token" parameter in the query string. Yet, I just tried it and no problem. +1Vigorous
Is it possible to not have the ?alt=media ?Dioptrics
@Roberto OOC, do the firebase storage security rules still work? or does anyone with the link have access to the file? If security yes, how is the heck is the auth being handled?? lolMagyar
Rules always run - no magic backdoor links if that is your thinking. If you don't provide a valid token, request.auth will be null. In the open rule set above, allow read: if true means everything passes for reads, including tokenless requests.Dincolo
C
20

With Firebase Storage, you're given two URLs that you can use to represent files:

// "Private" internal URL, only accessible through Firebase Storage API
// This is protected by Firebase Storage Security Rules & Firebase Auth
gs://bucket/object

// "Public" unguessable URL, accessible by anyone with the link
// This is secured because that token is *very* hard for someone to guess
https://firebasestorage.googleapis.com/v0/bucket/object?alt=media&token=<token>

The first option requires that you use the reference.getDownloadURL() method to convert the internal gs:// URL into a public https:// URL.

The second option allows you to share this public but unguessable URL with trusted individuals, and allows them to access content without authentication to Firebase or using your app--think sharing family photos with Google Photos. Likely this behavior will be good enough, unless you desire public sharing with clean URLs. You can use this URL in a browser, or use any other HTTP library to download it. We provide the ability to download these files as well (off a reference), so you don't need to get a third party library, you can just use us.

I strongly recommend reading our docs for more information on this.

Carr answered 5/8, 2016 at 15:48 Comment(16)
If you would like to share this link to the graph API with link=downloadURL, facebook logs the error: error link should represent a valid URL.Specialism
Does the token ever change? I'd like to save the full URL in the database associated with an object and use it later. (without using getDownloadUrl on a child)Thunderstone
@Specialism I'm willing to bet that this is because you're not properly URL encoding the firebase storage URL when you send it to Facebook.Carr
@Thunderstone the token changes when you overwrite the file, or if you invalidate the token in the web console.Carr
From backend perspective this answer is not useful. The mobile users don't have secure way to access the firebase store (except if they have account). So I have to create them download url , but there is not such method in the python Admin API or such REST functionality. So firebase give me no choice but to give public access (and I don't want to), or to have service that downloads the image through the backend using Google cloud storage and not firebase storage. So looks to me like the backend APIs or the admin API, is last concern, targeting mostly mobile users making firebase escape hard.Mikkel
@Mikkel if you're on the server, you can use the Cloud Storage Client Libraries (e.g. python: github.com/GoogleCloudPlatform/google-cloud-python) and generate a signed URL. That can be directly downloaded on the client and doesn't require making the file public.Carr
@MikeMcDonald I can't because Google are not supporting their own library google-cloud-python on Google App engine. github.com/GoogleCloudPlatform/google-cloud-python/issues/1893Mikkel
It does not generate two different URL.It basically returns the same URL which is in Firebase StorageIntermediacy
why token is needed when I can directly access the file from https://firebasestorage.googleapis.com/v0/bucket/object?alt=media ?Natashianatassia
If you're accessing it directly that means it's public. The point of the token is to make it private, so only those with the token can access it.Carr
@MikeMcDonald I don't understand. You say '"Public" unguessable URL, accessible by anyone with the link. This is secured because that token is very hard for someone to guess.'. But... If link works even without a token, then link isn't unguessable anymore. You don't need to guess a token. You need to guess only bucket and object name. Or the token is not required only if you make the object allowed to read by anyone like in fionbio's answer?Paulpaula
@RuslanStelmachenko correct, if your read rules allow public read access you don't need a token. Obviously, we don't recommend public read access to objects unless they truly are public. It's easy to use read:false globally and only generate sharable URLs if that's how you want to use the app, though we recommend using Security Rules for more control over access.Carr
Is there a "I could careless about security, just give me a public link I can use on all images for my bucket with out running getdownloadurl option"?Autum
@Autum if you're dead set on this you can set the security rules to public and just use the https://firebasestorage.googleapis.com/v0/b/{bucket}/o/path/to/file and it should workCarr
Awesome, thank you!!! I'm a little surprised to not find that much info on this tip. I realize the firebase way is to programmatically get the download link but in a web environment you just slap the images in a public folder and can href them. @MikeMcDonaldAutum
Because if you're hosting public, static content you should just upload it to Firebase Hosting and serve it from there rather than upload to a GCS bucket and then pull it in.Carr
P
9

Year 2020, I had quite a hard time figuring this out, especially because of the limitations of the CharacterSet in Swift for encoding a String (or most probably I'm missing something).

Here are the steps how I managed to convert a "path" (folder path) of a Blob on Firebase Storage (after upload).

  1. Given a storage metadata after upload, (in iOS, we have the class called FIRStorageMetadata.) get the string objects called path and bucket.
  2. Encode properly the path string! This is important! If you miss a character, obviously you'll get an error when you attempt to download the complete direct URL.

    • In iOS, I encode the path string using the CharacterSet urlHostAllowed. BUT, this is not enough, like I said in the above, it is either there is no CharacterSet that encodes a string into a URL including the "+' plus sign. So after encoding using the urlHostAllowed, I call replace occurrence string method, replace "+" with "%2B"
    • One way to test if you are encoding the path string correctly is to compare your encoding result with the one you can get from the Firebase Storage UI.
  3. Concatenate the strings:

Voila!

FAQs

  1. Can we omit the token? Yes, certainly. It just works. Been doing it ever since I learned it.
  2. Can we omit the ?alt=media? Nope! You'll just get a string in json format and not the file.
Plutonian answered 21/2, 2020 at 16:10 Comment(0)
L
8

For those who just want to get a link

In console > Storage

Select a specific photo and you will see the link below. enter image description here

Lundt answered 13/5, 2018 at 9:9 Comment(2)
this no longer seems to apply?Imprest
It works like this: github.com/firebase/firebase-admin-node/issues/694Ascending
L
4

To convert into a public URL check example.

Suppose the link is gs://funzone-website.appspot.com/public/logo.jpg

let g=funzone-website.appspot.com/public/logo.jpg

replace file path with % if there is a folder. In the above example, the public is a folder, add ?alt=media and add o.

Now g=funzone-website.appspot.com/o/public%2Flogo.jpg?alt=media

convert and replace path(/) with %2F

To convert this use https://firebasestorage.googleapis.com/v0/b/{g}

or

https://firebasestorage.googleapis.com/v0/b/funzone-website.appspot.com/o/public%2Flogo.jpg?alt=media

If there is no folder(public) then the link is

https://firebasestorage.googleapis.com/v0/b/funzone-website.appspot.com/o/logo.jpg?alt=media

Livelihood answered 27/1, 2021 at 13:49 Comment(1)
it worked, but we must set rules to the specific folder to true, ie no authendications otherwise it throws errorProbationer
S
2

2020

Firebase is connected to Google Cloud Platform:

You need to make the bucket or the desired objects public on Google Cloud Platform and there you will get a simple link without any need to edit it:

Making data public

You can also use the link without making the data public (but then you will have to be signed in to access) :

Go to Google Cloud Platform > select your project > Storage > Browser > Open bucket appID.appspot.com > open any object and there you have both uri (that Firebase console provides) and the URL.

  • I tried all the given methods here but they don't work anymore
Sulphur answered 7/4, 2020 at 21:15 Comment(0)
I
0

Another option is an URL of the format:

https://storage.googleapis.com/PROJECT-ID/FILEPATH

PROJECT-ID: project ID of Firebase project

FILEPATH: path to project file

Imprest answered 13/3, 2020 at 6:49 Comment(0)
P
0
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow  write: if request.auth != null;
      allow  read: if request.auth == null;
    }
  }
}

You can try this because it allow public read access

Proboscis answered 17/10, 2021 at 16:44 Comment(0)
B
0

If your want your images to be public -

Add this to your storage rules

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

And then you can use it like

export const getMedia = (folderId, mediaId) =>`https://firebasestorage.googleapis.com/v0/b/${process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET}/o/${folderId}%2F${mediaId}?alt=media`;
Borzoi answered 6/5, 2023 at 9:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.