How to get Firebase storage URL - firebase

I am sending FCM notifications with image links from my backend written in Go. The images are stored in Firebase-storage. I need to resolve the bucket path into a Url that I can use to create the FCM notification.
There seems to be a Javascript function (getDownloadUrl) to do this. How do I get the download URL in Go?

getDownloadUrl is a feature of Firebase client SDKs that read and write Cloud Storage. There is no direct equivalent for backend and server SDKs.
Cloud Storage has a similar concept called signed URLs that you can use to create URLs that directly access content in Cloud Storage. You can use the REST APIs directly as shown in the documentation, or if you're using the Go SDK, you can simply call SignedURL directly to get a URL that meets your specifications.

Related

Using Firebase Auth Credentials to Access FirebaseStorage REST API

I am trying to use Firebase Auth credentials to access FirebaseStorage bucket. I have been successful in using the REST API https://firebasestorage.googleapis.com/v0/b/BUCKET_NAME/o/ to perform uploads and downloads; even though the official documentation requires to use https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=media&name=OBJECT_NAME for uploads and https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME?alt=media for downloads, I am unable to use Firebase Auth credentials for them.
I am trying to implement resumable uploads and initiating it using https://firebasestorage.googleapis.com/v0/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME but there is no SESSION-URI that is returned. I tried to create my own URI using the id from the X-GUploader-UploadID header to create the URI in the format https://firebasestorage.googleapis.com/v0/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME&upload_id=UPLOAD_ID to start a single chunk upload but I got a Not Found error.
I need help on either rectifying that or using Firebase Auth to access the https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME REST API

Can I make firebase file URLs publicly available without requiring token?

I am using firebase to allow users to upload their files to the Storage buckets. I was using the getDownLoadURL() to fetch the publicly available URL...however, this comes with an embedded token to allow access to the file.
In my same app, I'm using the Google Document viewer which takes a URL to preview the doc. Unfortunately, the Google Doc Viewer does not work with the firebase URLs's with the embedded token.
In Google Console, on an individual file, I click to make it public. In that case, the URL is now reachable via the https://storage.googleapis.com// format...and I don't need to use the token which works great.
So, what I want to do is mark/make a file public when I'm uploading it to firebase. I have reviewed the firebase docs and there doesn't seem to be a makePublic() method like there is on the Google API's.
Is there a way I can mark a file as public during upload, so that it can be accessed without any token?
The other solution was that I could update the bucket to be accessible, but this makes it totally open to be browsed at https://storage.googleapis.com/, which I don't want to do.
The client-side Firebase APIs don't know anything about the underlying Google Cloud Platform configurations for public content in storage buckets. So that won't be an option.
You will have to involve some backend code to change the object's configuration after it's uploaded. You could set up your own API endpoint via Cloud Functions (or whatever backend you want) to run one of the Google Cloud Storage server SDKs to set the file as public. (You will probably also want some way to authorize that the user calling your API should be able to make this change.)

Getting a client URL to Firebase Cloud Storage that comply with storage rules

I have a web application on Firebase where I create a Firestore document with a reference to a Firebase Storage file.
I've setup rules on Firebase Storage to only allow read: if request.auth != null.
Since Firestore complies with similar rules I am able to ensure that access to my Firestore document is only possible, when a user is authenticated, but how do I best about enforcing the same rule in my web application to the Firebase Storage file?
I can use getDownloadUrl() when I've uploaded the file and store the URL in my Firestore document. - But URL is always public to anyone
I can create a Firebase Function that on each request checks authentication and if authenticated, generate a getSignedUrl() with an expiration of say 5 minutes and then do a 302 redirect to the temp public URL - but that does not comply with Firebase Storage rules so I need to replicate any new rulesets in the function
Why can't Firebase Storage not simply behave like Firestore and check the auth on a http request and return the file is it complies with rules?
Am I totally missing a 3) and better option to make sure a user is logged in before accessing a file from storage?
According to the Cloud Storage for Firebase Documentation you can now access files through the Web SDK.
From version 9.5 and higher, the SDK provides these functions for
direct download:
getBlob()
getBytes()
getStream()
Using these functions, you can bypass
downloading from a URL, and instead return data in your code. This
allows for finer-grained access control via Firebase Security Rules.
I can use getDownloadUrl() when I've uploaded the file and store the URL in my Firestore document. - But URL is always public to anyone
It may not be very clear from the documentation, but that's exactly the way download URLs were designed to work.
Why can't Firebase Storage not simply behave like Firestore and check the auth on a http request and return the file is it complies with rules?
It behaves like that when you use the provided client SDK to download files (not using download URLs). Unfortunately, the web SDK doesn't have a file download API (while Android and iOS do).
If you would like to file a feature request for the web SDK, that should go to Firebase support. For now, you have to use download URLs, which are publicly accessible. Or you can create your own backend endpoint that verifies an auth token provided by the client using the Firebase Admin SDK. The backend code can decide if the user should get be able to get the file contents.

How to use firebase storage along with custom server?

I am planning to use firebase storage as storage bucket for images for my app.
Shall I use client side firebase SDK to upload images directly to firebase or, shall I send image to my server first and use firebase Admin-sdk and let the server upload image to firebase? Also I have other data along with image which client will send, that server needs to handle.
EDIT: I was confused about one thing, if I use firebase admin-sdk, first my image need to upload to the server and then server will send it to firebase storage, won't it double the upload time?
Both are valid options, and neither is pertinently better than the other.
I typically prefer using the Firebase SDK to upload to Cloud Storage, since it saves me from having to come up with my own client-side code and handling things like network detection, retries, etc. I then often write metadata about the file to the Firebase database (either the Realtime Database, or Cloud Firestore) and use that to trigger Cloud Functions to do any backend processing that is needed on the image.
But it's equally valid to write your own server-side endpoint that does the processing of the image, and post to that from within your app.

How to upload the files to firebase storage with uid using Post Url?

I found one solution to upload the file to firebase storage without any authentication using this link How to upload objects to Firebase Storage using Postman for testing?
The above-mentioned case works only when my firebase storage looks like this, (Without any security restriction)
allow read, write;
But, Now I want to achieve this with some security restrictions.
Is there any way to upload the files to firebase storage by POST URL (Postman) with some security restriction.
I tried to achieve this by
https://firebasestorage.googleapis.com/v0/b/projectName.bucketName.com/o?uploadType=media&name=picture2&auth=uid
But it shows 403 - forbidden error.
There is no public REST API for uploading file to Cloud Storage for Firebase. The end point you're trying to reach is meant for use by the Firebase SDK only, and is neither documented, nor supported for use beyond that.
That said, you may be able to mint a token using the Firebase Authentication REST API, and pass that along to the request you have. But as said, it won't be supported and may change without warning.
The most common approach for REST uploads is through the Google Cloud Storage API, around which the Firebase APIs are a friendly wrapper. But these APIs are meant for access from trusted code, so wouldn't be using the Firebase Authentication UID of your users. The best I can think of is to write a Cloud Function that handles the user authentication and authorization, and then use the Google Cloud Storage Node.js or REST API to upload the file.
I use this endpoint on my project
https://firebasestorage.googleapis.com/v0/b/YOUR_BUCKET/o?uploadType=media&name=YOUR_FILE_PATH_AND_NAME
and add headers on your post
headers.Add("Authorization", "Bearer " + FirebaseAuthIDToken);
headers.Add("Content-Type", "application/octet-stream");

Resources