4
votes

I am using the firebase-tools shell CLI to test Firestore cloud functions.

My functions respond to the onCreate trigger for all documents in a certain collection, by using a wildcard, and then mutate that document with an update call.

firestore
    .document(`myCollection/{documentId}`)
    .onCreate(event => {
      const ref = event.data.ref
      return ref.update({ some: "mutation"})
    })

In the shell I run something like this, (passing some fake auth data required by my database permissions):

myFunction({some: "data"}, { auth: { variable: { uid: "jj5BpbX2PxU7fQn87z10d4Ks6oA3" } } } )

Hoever this results in an error, because the update tries to mutate a document that is not in the database.

Error: no entity to update

In the documentation about unit testing it is explained how you would create mocks for event.data in order to execute the function without touching the actual database.

However I am trying to invoke a real function which should operate on the database. A mock would not make sense, otherwise this is nothing more then a unit test.

I'm wondering what the strategy should be for invoking a function like this?

By using an existing id of a document the function can execute successfully, but this seems cumbersome because you need look it up in the database for every test, and it might not be there anymore at some point.

I think it would be very helpful if the shell would somehow create a new document from the data you pass in, and run the trigger from that. Would this be possible maybe, or is there another way?

1
Use the local emulator as described here. You need Firebase CLI version 3.15.1 or later. firebase.google.com/docs/functions/…Doug Stevenson
@DougStevenson Yes I know. You already answered this in my previous question about Firestore cloud functions :) I am using the latest version. This is mainly about being able to test onCreate trigger without having to invoke them on already existing documents. Sorry if I wasn't clear.Thijs Koerselman
I have changed the title to avoid confusionThijs Koerselman
You can use the firebase shell to simulate triggers stackoverflow.com/questions/46614685/…Damien Romito

1 Answers

0
votes

The Cloud Functions emulator can only emulate events that could happen within your project. It doesn't emulate the actual change to the database that would have triggered it.

As you're discovering, when your function depends on that actual change previously occurring, you can run into problems. The fact of the matter is that it's entirely possible that the created document may have already been deleted by the time you're handling the event in the function (imagine a user acts quickly to delete, but the event is delayed for whatever reason).

All that said, perhaps you want to use set() with SetOptions that indicate you want to merge instead of overwrite. Bear in mind that if the document was previously deleted (with good reason) before the event triggered, you'll unconditionally recreate the document, which may not be what the user wanted.