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

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");

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 get Firebase storage URL

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.

Pass user auth to Firestore from Cloud functions

So I'm trying to build an http endpoint using a Cloud function. This cloud function is only invoked after the user signs in. So I can pass the user token and verify it on the server side. I understand how to do this.
I also have security rules on my Firestore collections with authorization rules set up using request.auth.uid. This also just works if I use the firebase web sdk.
But my question is - how do I use the same authorization rules via cloud functions? I don't want to rewrite my auth logic separately for the http endpoint.
Security rules only apply to access from web and mobile SDKs. It does not apply to code using any of the server SDKs, including the Firebase Admin SDK and anything you would use with Cloud Functions. You will have to apply your own logic to check the validity of data before it's added to Firestore. The same is true for Realtime Database and Cloud Storage security rules.
As you use the admin sdk in your functions, the check for the auth looks a bit different. Just watch this video from The Net Ninja. He is explaining how to do this. Just use the generated token instead what’s been used in the video.

Resources