2
votes

I'm trying to publish a message to GCP PubSub when a document in Firestore is written.

I have gotten it to work but with a function that is listed as deprecated. When I attempt to use the newer function I get an error.

I'm using the documentation from here. publish is listed as deprecated and points to publishMessage as its replacement.

The error I receive when using the publishMessage function is 'TypeError: Data must be in the form of a Buffer.'

Any idea on what I am missing with the publishMessage syntax?

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const firestore = admin.firestore();
const {PubSub} = require('@google-cloud/pubsub');
const pubsub = new PubSub(MY_PROJECT);

exports.pubSubPublishTest = functions.firestore.document('pubSubTest/{docID}').onWrite((change, context) => {
  const topic = pubsub.topic('test');
  const otherBuffer = Buffer.from('this is the message');

  const callback = (err, messageId) => {
    if (err) {
      console.error(`error encountered during publish - ${err}`);
    } else {
      console.log(`Message ${messageId} published.`);
    }
  };

  // this worked, but the function is listed as deprecated
  topic.publish(otherBuffer, callback);

  // this did not work - {otherBuffer} is from  the doc
  // but I also tried without the curly braces and received the same error.
  //topic.publishMessage({otherBuffer}, callback);

  return null;
});
1

1 Answers

3
votes

The API documentation you linked to is suggesting that you provide a MessageOptions object as the first parameter. According to the API docs for that object, you have to compose an object that contains one of the options for specifying the payload. If you have a node Buffer, you should compose the object like this:

topic.publishMessage({data: otherBuffer}, callback);

This method is asynchronous, and returns a promise to indicate when the message is sent.

Bear in mind also that you need to return a promise from your function that resolves only after all the async work is complete. Returning null as you are now is not going to work. You should use the promise returned by publishMessage() to tell Cloud Functions that your work is complete and it's safe to clean up.

return topic.publishMessage(...);

I suggest also looking into using that promise instead of the callback function to continue with additional work (such as your logging). Learning how to deal with promises effectively is absolutely crucial to writing effective JavaScript in a Cloud Functions environment.