Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access a cloud firestore document within a cloud function

Within my Google Firebase Firstore database I would like to gather aggregative data such as how many documents a collection has. Since Firestore does not provide aggregative queries I'm attempting to write a cloud function that will increment a field every time a document is added to the database which will contain the number of documents a collection has.

The problem I'm having is I cannot for the life of me figure out how to grab documents from Firestore within a cloud function using nodejs.

Here's what I'm doing:

At the top of my index.js file I configure the admin SDK and what have you like this:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

Then for my cloud function I do this:

exports.createPost = functions.firestore
  .document('posts/{post_id}')
  .onCreate(event => {

    // Get the post object
    var post = event.data.data();

    var senderID = post["sender_id"]; // This is not null

    // Access to user's document and the main ledger document
    const userDocRef = admin.database().ref('/users').orderByChild("user_id").equalTo(senderID).once('value')
    const ledgerDocRef = admin.database().ref('/posts/ledger').once('value');

    return Promise.all([userDocRef, ledgerDocRef]).then(snapshot => {

        const user = snapshot[0].val();
        const ledger = snapshot[1].val();

        console.log("user => "+user); // Logs: user => null
        console.log("ledger => "+ledger); // Logs: ledger => null

        const userPostCount = user["user_name"];
        const globalPostCount = ledger["global_post_count"] + 1;

        const userUpdate = user.update({"post_count" : userPostCount});
        const ledgerUpdate = ledger.update({"global_post_count" : globalPostCount});

        return Promise.all([userUpdate, ledgerUpdate]);
    });
});

I end up with the error:

TypeError: Cannot read property 'global_post_count' of null at Promise.all.then.snapshot

Which I figure means something is wrong with my query but I don't know what. Both the users and posts are root level collections.

Im also getting a warning that says:

Billing account not configured. External network is not accessible and quotas are severely limited.

From what I've read online, I don't think that effects it but I thought it was worth noting.

Please help.

like image 984
Garret Kaye Avatar asked Oct 17 '17 04:10

Garret Kaye


People also ask

Do firestore rules apply to cloud functions?

Since Cloud Firestore backend SDKs running in Cloud Functions have privileged access to Cloud Firestore, they will bypass all security rules.

Which function is used to fetch data from the firebase document?

The Get() function in Go unmarshals the data into a given data structure. Notice that we used the value event type in the example above, which reads the entire contents of a Firebase database reference, even if only one piece of data changed.


1 Answers

Looks like you've written a Firestore trigger, but are then reaching into Realtime Database for queries:

const userDocRef = admin.database().ref('/users').orderByChild("user_id").equalTo(senderID).once('value')
const ledgerDocRef = admin.database().ref('/posts/ledger').once('value');

If your RTDB is empty, these queries will also end up empty.

To query Firestore, you need to be using admin.firestore() instead of admin.database(). Firestore has a mostly different API (via the Cloud SDK I just linked) than RTDB, but they are similar in some ways.

like image 149
Doug Stevenson Avatar answered Sep 24 '22 12:09

Doug Stevenson