Firebase One-time Functions
Asked Answered
A

2

9

I'm sure these are common scenarios, but after researching some hours, I couldn't really find what the common practice is. Maybe someone with more experience in Firebase can point me to the right direction.

I have two particular scenarios:

1. Code that runs once

Example 1: adding new data to all users in firestore, which is needed for a new feature
Example 2: start duplicating data into existing documents

I currently write the code in a cloud function, and run it on a firestore event (onUpdate of a "hidden" document) and then I immediately delete the function if everything goes well.

I also increase the timeout and memory for this function, as the idea is to potentially update millions of documents.

2. Manually trigger a function from the firebase console (or command line)

Example: Give a user admin privileges in the app (function that sets custom claims and firestore data). We don't have time to implement a back-office, so doing this from the firebase web portal/console would be ideal, specifying the user id.

My current solution is to use a https function, and run it from the GCP portal (on the function's "Testing" tab, being able to pass a json). BUT the function can be triggered publicly, which I don't really like...

What are the common practices for these scenarios?

Arabian answered 5/3, 2020 at 23:29 Comment(2)
In both cases I’d use command line Node scripts. For the second example you could build a very simple admin UI with the Firebase admin SDK if you have the time and non-techies need to be able to make these changes.Impudent
Thanks @KevinRenskers, I will look that up!Arabian
I
10

To expand on my comment: if you want to create a node script to run one-off code, you just write your JS code like for any cloud function but simply run it immediately. Something like this.

const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();

db.collection('users')
  .where('myField', '==', true)
  .get()
  .then(querySnapshot => {
    querySnapshot.docs.forEach(doc => {
      // update doc
    });
  });

If you save this as script.js and execute it with node script.js you’ll be pointed towards downloading a JSON file with credentials. Follow the instructions and you can then run the script again and now you’re running your own code on Firestore, from the command line.

Impudent answered 6/3, 2020 at 13:7 Comment(2)
So simple, I don't know how I missed this on my research. And I guess this does not have time and memory limitations like Cloud Functions, which is perfect for big firestore data changes (or even better, doing this on a Google Shell). Thanks again :)Arabian
Is it possible to run this against a local emulator?Amoreta
J
4

For administrative type operations, you're better off just running them on your desktop or some other server you control. Cloud Functions is not well suited for long running operations, or things that must just happen once on demand.

Case 1 really should be managed by a standalone program or script that you can monitor by running it on your desktop.

Case 2 can be done a number of ways, such as building your own admin web site. But you might find it easiest to mirror the contents of a document to custom claims using a Firestore trigger. Read this: https://medium.com/firebase-developers/patterns-for-security-with-firebase-supercharged-custom-claims-with-firestore-and-cloud-functions-bb8f46b24e11

Jabber answered 5/3, 2020 at 23:37 Comment(1)
Lightning fast answer! Case 2: This tutorial is perfect, and very well done, awesome work. Case 1: Got it, is that like a local Cloud Function? Something like https://firebase.google.com/docs/functions/local-emulator maybe? Kevin mentioned Command Line Node Scripts. Is there a blog article about this for firebase? As a suggestion, maybe under "Solutions" in the Firestore docs, to add a page "One-time Scripts" with examples. Coming from iOS, and not being very experienced in node, it would be nice to have a quick & easy recipe to get me started with this. Thanks :)Arabian

© 2022 - 2024 — McMap. All rights reserved.