How to trigger onCreate in Firestore cloud functions shell without using an existing document

Viewed 2717

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 Answers

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.

Related