2

Cannot get Firebase Cloud Functions for Firestore to trigger on onWrite of my collection. Trying to setup device to device push notification for chat app. Function is deployed and on Pay as you go plan, however, changes in document, updates or create in "chats" collection is not triggering. Firebase cloud messaging is supposed to send a push and write to the log. Neither is happening. Push is working with other sources.

Thanks for your help, wish device to device push notifications was easier, plan is to watch the chat document and fire push notifications on update or create of new conversation. Open to other ideas. Thanks

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

exports.sendNotification = functions.firestore
  .document('chats/{chatID}')
  .onWrite((data, context) => {
    // Get an object representing the document
    console.log('chat triggered');
    // perform desired operations ...

    // See documentation on defining a message payload.
    var message = {
      notification: {
        title: 'Hello World!',
        body: 'Hello World!'
      },
      topic: context.params.chatID
    };

    // Send a message to devices subscribed to the provided topic.
    return admin.messaging().send(message)
      .then((response) => {
        // Response is a message ID string.
        console.log('Successfully sent message:', response);
        return true
      })
      .catch((error) => {
        console.log('Error sending message:', error);
      });

  });

UPDATE: I'm using "firebase-functions": "^1.0.1"

UPDATED: Updated the code to reflect what we currently have deployed, still not working.

ansidev
  • 361
  • 1
  • 3
  • 17
iOSDevSF
  • 1,169
  • 1
  • 13
  • 24
  • 1
    Do you see an error message in the Functions log? – Renaud Tarnec May 07 '18 at 04:47
  • No errors in the functions log. Can’t get the method to trigger a log statement either – iOSDevSF May 07 '18 at 14:16
  • 1
    What do you exactly mean by "Can’t get the method to trigger a log statement either". In the Firebase console, in a browser (https://console.firebase.google.com/), if you select "Functions" in the vertical menu and select the "LOGS" tab, you will see the log from the Functions. – Renaud Tarnec May 07 '18 at 14:39
  • The log has no errors in it. Only thing in there is info statements with deploy times. – iOSDevSF May 07 '18 at 15:35
  • 1
    I'm not clear on the logs you're seeing. Do you see a log indicating `sendNotification Function execution started`? – Bob Snyder May 07 '18 at 16:11
  • No, that is the problem – iOSDevSF May 07 '18 at 16:28
  • I'm using "firebase-functions": "^1.0.1" – iOSDevSF May 07 '18 at 16:33
  • 1
    How are you writing the Firestore data at `chats/{chatID}`, code or the Firebase Console? If code, edit your post to include it. – Bob Snyder May 07 '18 at 16:34
  • console.log('chat triggered'); – iOSDevSF May 07 '18 at 16:51
  • 1
    My question was about how you are writing to the Firestore database, not the log. Whatever method you use, do you see the data change in the Firebase Console Database tab? – Bob Snyder May 07 '18 at 17:17
  • @BobSnyder we are not writing to the database at all. – iOSDevSF May 07 '18 at 18:16
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/170565/discussion-between-iosdevsf-and-bob-snyder). – iOSDevSF May 07 '18 at 18:19
  • You should review the [Cloud Function intro docs](https://firebase.google.com/docs/functions/?authuser=0): _Cloud Functions for Firebase lets you automatically run backend code in response to events triggered by Firebase features and HTTPS requests_. You need provide a triggering event (Firestore write or another supported action) to cause your cloud function to execute. – Bob Snyder May 07 '18 at 19:48
  • @BobSnyder I'm not an idiot, I've been triggering events for days now and they aren't logging. Thus this post. Do you really think I would post here before checking the docs? – iOSDevSF May 07 '18 at 21:09
  • My comment was because I asked "how you are writing to the database" to trigger your Cloud Function and you responded "we are not writing to the database at all". – Bob Snyder May 07 '18 at 21:18
  • Having the same exact issue! I am writing to the db through the emulator. I wonder if the solution is any different when running from emulator. – Zorayr Jun 01 '20 at 06:59
  • did any one find solution for this? – Ahmed Saeed Jun 28 '20 at 21:12

3 Answers3

2

There are chances you are using the old syntax (before V1.0) with the new library (v1.0). See the Migration Guide: https://firebase.google.com/docs/functions/beta-v1-diff and check the version in your package.json file.

In addition, note that a Cloud Function must always return a Promise (or if you cannot, at least a value, for asynchronous functions). See this documentation (and associated video) which explain that in detail: https://firebase.google.com/docs/functions/terminate-functions

You should modify you code this way:

If you are using Cloud Functions 1.0 or above:

exports.sendNotification = functions.firestore
    .document('chats/{chatID}')
    .onWrite((change, context) => {

Returning:

exports.sendNotification = functions.firestore
.document('chats/{chatID}')
.onWrite((change, context) => {
  // Get an object representing the document
   console.log('chat triggered');
  // perform desired operations ...

    // See documentation on defining a message payload.
    var message = {
      notification: {
        title: 'Hello World!',
        body: 'Hello World!'
      },
      topic: context.params.chatID.   //<- If you are using a CF version under v1.0 don't change here
    };

    // Send a message to devices subscribed to the provided topic.
    return admin.messaging().send(message).  //<- return the resulting Promise
      .then((response) => {
        // Response is a message ID string.
        console.log('Successfully sent message:', response);
        return true;    //<- return a value
      })
      .catch((error) => {
        console.log('Error sending message:', error);
        //return.  <- No need to return here
      });

});
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
1

Your firebase-admin initialization syntax, admin.initializeApp(), suggests you are using Cloud Functions SDK version 1.0.x. The parameters for onWrite() have changed in version 1.0.x from earlier versions. You also need to return a Promise for asynchronous action admin.messaging.send(). The three needed corrections are noted below:

exports.sendNotification = functions.firestore
    .document('chats/{chatID}')
    .onWrite((data, context) => {  // <= CHANGE
      // Get an object representing the document
       console.log('chat triggered');
      // perform desired operations ...

        // See documentation on defining a message payload.
        var message = {
          notification: {
            title: 'Hello World!',
            body: 'Hello World!'
          },
          topic: context.params.chatID // <= CHANGE
        };

        // Send a message to devices subscribed to the provided topic.
        return admin.messaging().send(message)  // <= CHANGE
          .then((response) => {
            // Response is a message ID string.
            console.log('Successfully sent message:', response);
            return
          })
          .catch((error) => {
            console.log('Error sending message:', error);
            return
          });

});
Bob Snyder
  • 37,759
  • 6
  • 111
  • 158
  • 1
    Doesn't work for me... I am running inside an emulator for both functions as well as firestore. – Zorayr Jun 01 '20 at 07:01
  • @Zorayr, it seems you are not using a token or topic when sending a message. That might be your issue. Either way, I'm sending message to a topic and my functions are not triggering anything on the function console. – Axes Grinds Aug 15 '20 at 22:18
0

For me the issue was I was writing data that already existed in Firestore. The onWrite isn't triggered apparently if the data you're writing is exactly the same as what is there.

odiggity
  • 1,496
  • 16
  • 29