Reference path for service account key - firebase

I am referring to the next article what is "serviceAccountKey.json" referring to in the Firebase device-to-device notifications tutorial
There is one statement written in the index.js file
var serviceAccount = require("path/to/serviceAccountKey.json");
I would like to know what would be the path here when writing the script in the google cloud function web interface.
Do I have to upload the json file on a bucket and then give the bucket reference path?

You should put your serviceAccountKey.json in the same folder as your index.json. Then when you deploy to Cloud Functions, both the code and the key file will be uploaded and you can refer to the JSON from the code with:
var serviceAccount = require("./serviceAccountKey.json");
Note that you may want to consider using the Admin SDK for Firebase Cloud Messaging to send messages these days. This SDK didn't exist when I wrote blog post, but makes the code for sending messages simpler (at the cost of using an extra SDK).

Related

Isn't it a bad idea to store your service account key in the code? Firestore documentation is saying I should [duplicate]

This question already has answers here:
Is it safe to expose Firebase apiKey to the public?
(10 answers)
Closed 1 year ago.
It is very likely the case I am misunderstanding how all of this works as I am still a newer programmer, but in every course I have taken I have been told not to expose any credentials within the code.
In this Firestore documentation, it tells you to store your service account's credentials as a JSON file and include the file in the directory for the SDK to access. Am I wrong in thinking this is a security issue?
Firestore Getting Started Documentation
Under Initializing Firestore
To use the Firebase Admin SDK on your own server (or any other Node.js environment), use a service account. Go to IAM & admin > Service accounts in the Cloud Platform Console. Generate a new private key and save the JSON file. Then use the file to initialize the SDK:
const serviceAccount = require('./path/to/serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
const db = admin.firestore();
Am I missing something here? Why is it okay to do this?
In fact it depends how we interpret "not to expose any credentials within the code."
Firstly, a main important rule, is to never include secrets (password, or service account keys, or any other confidential data) into the source code, and especially in source code configuration (git / github).
Secondly, in some situation, the only solution to authenticate to a service or API is to use a service account key. In this case, we must keep this file separated from source code, and provide it to app by an environment variable pointing to it.
If your code is running on Google Cloud Platform (App Engine, Cloud Functions, Cloud Run, Firebase Functions...), you can use default authentication provided directly by GCP, and avoid any service account key.
Check Firebase documentation.
In this case, you keep it just for development purpose on your local machine.

source bucket is not visible in Firebase Firestore import web tool even after giving required permission

I'm following the official docs on how to export and import firebase firestore data between 2 projects.
I'm able to export firestore data to a bucket. https://console.cloud.google.com/firestore/export
But I don't see that bucket when I try to import in a different firebase project. https://console.cloud.google.com/firestore/import
I gave Storage Admin permission to the destination service account i.e. dest-proj#appspot.gserviceaccount.com and both projects and this bucket is stored in the same multi-region (us-centeral)
I'm aware of the other way to import-export using gcloud shell but why this method is not working?
The console only browse buckets that exist inside your current project. If data is coming from an outside bucket, you can simply type its entire file path in the Filename field as shown on the image below.
It will succeed if the service account running the import have the right IAM permission on the separate source bucket.

Firebase Storage clone uploaded file and create new file without downloading/uploading possible?

let's say I have an image /path/image1.png in the firebase storage. I want to copy this image and create a new image with a different name but the same content as /path/image2.png. I'm using AngularFire. How will I achieve this? Please help
Firebase Storage (nowadays called Cloud Storage for Firebase) is a set of client-side SDKs that allow you to access Cloud Storage from within your application.
There is no Firebase API to create a copy of a file in Cloud Storage. It's a valid use-case though, so I'd recommend you file a feature request for it.
In the meantime, the two options I can think of are:
Read the data to the client, and write it to the new location. This is definitely wasting bandwidth for the client, so I'd only consider it if your files are quite small, and your clients have a decent connection.
Use one of the (non-Firebase) server-side SDKs for Cloud Storage to create a copy of the file. For example, you could wrap this Node.js code in a callable Cloud Function and then call that from your application code.
await storage
.bucket(srcBucketName)
.file(srcFilename)
.copy(storage.bucket(destBucketName).file(destFilename));

How can I reference a GCP cloud storage object, from the firebase download link, using the Admin SDK

My question is similar to this: Firebase web: Storage Location from Download URL
I'm writing a firebase function where i need storage location. Right now i have download url:
https://firebasestorage.googleapis.com/v0/b/dxxxxxxxxx.com/o/videosvideo%3A67423?alt=media&token=acxxxxxxxxxxxxxxxxx
Is there a way to get Storage location like this:
gs://dexxxxxxxxxxxxxx.com/videosvideo:67423
The answer given is to do:
const downloadUrl = "https://firestorage.googleapis...";
const gsUrl = firebase.storage().refFromUrl(downloadUrl).toString();
However, the context I'm doing this, is as a Firebase Function - so I need to use the Admin SDK.
The Admin SDK Storage directly references the the GCP Storage Buckets, which don't have refFromUrl().
Is there a simple way to do this? The context is - I want to delete the object for the given download link.
I don't think there is a server side API that's going to do what you want. I'd recommend storing not just the download URL in your database, but also the path to the file in storage. That way, the server can deal with the file easily through the Admin SDK.

How can I generate a "Download URL" with a token using the management API, and is that what I want?

I am trying to build a Firebase admin utility that I can use to upload files to Firebase Storage and then return a long lived URL that I can store in the Firebase Realtime DB to access this file.
I believe I can do this in the Firebase Console by going to my project's console, clicking Storage on the left, clicking Upload File. Once the file is uploaded, I can get a URL by selecting the file in the list to open the right information pane, and then expanding the File Location section.
In that section there is a Download URL which appears to be a long lived but revocable URL containing a token of some type. Is this URL safe to store in a DB for long term storage? It does appear to be the same URL that is returned from the file upload api, which another Google Codelab (for Flutter) showed being stored in the realtime database.
However, I cannot figure out how to generate that type of URL from the Firebase Storage Management API. I am using NodeJS, but it should apply to all versions of the API AFAIK. I can only find a getSignedUrl call which does not seem to return the same URL, and appears to be time limited and containing a link to the service account...not what I want to store in a database.
let bucket = admin.storage().bucket();
bucket.upload('innovation3.jpeg', {destination: 'image_assets/innovation3.jpeg'},
function(err, file) {
file.getSignedUrl({action: 'read'},
function(err, url) {
console.log('Url: ' + url);
})
});
Is it possible to get this URL from the Management API, or do I need to use some other method. What is recommended?
Signed URLs created with the Firebase Admin SDK (backed by the the Cloud Storage SDK) are different from Download URLs created by the Firebase client SDKs. They serve the same general purpose, but you can expect them to look different from each other. They are both safe to store long term, except you should know that Signed URLs have an expiration date, which are you not specifying in your call. In that case, I don't know what the effective expiration is going to be.
Each invocation of getSignedUrl will generate a new URL. There is not just one that's unique to the file.

Resources