Home > Software engineering >  How to handle asyc/await data from firebase cloud function
How to handle asyc/await data from firebase cloud function

Time:11-01

im trying to learn how to query data from firestore in a cloud function but I keep getting stuck.

I cant use async/await for some weird reason...

my goal is to query the collection "chat" for a document with the doc id of "chatId" and get the value of "Job users data" ( see image below )

firebase data structure

exports.onChatMessageCreate = functions.firestore
    .document("chat messages/{docId}")
    .onCreate( (snapshot, context) => {
      const snapData = snapshot.data();
      const userName = snapData["userName"];
      // fetch user to send message to
      const chatId = snapData["Chat id"];

      // eslint-disable-next-line max-len
      const collectionRef = admin.firestore().collection("chat").doc(chatId).get().then( (value)=> console.log(value));
      console.log("below::");
      console.log(collectionRef);

      const payload = {
        // eslint-disable-next-line max-len
        notification: {title: userName, body: snapshot.data()["Chat message"], sound: "default"},
        // eslint-disable-next-line max-len
        data: {click_action: "FLUTTER_NOTIFICATION_CLICK", message: "Sample Push Message"},
      };

      try {
        admin.messaging().sendToDevice(tokens, payload);
        console.log("NOTIFICATION SEND SUCCESFULLY");
      } catch (e) {
        console.log("ERROR SENDING NOTIFICATION");
        console.log(e);
      }
    });

here is the image of the firebase logs:: firebase logs

I TRIED THE FOLLOWING CODE BUT I GET AN ERROR BECAUSE OF THE ASYNC

exports.onChatMessageCreate = functions.firestore
  .document("chat messages/{docId}")
  .onCreate(async (snapshot, context) => {   // ERROR FROM ASYNC
    const snapData = snapshot.data();
    const userName = snapData["userName"];
    // fetch user to send message to
    const chatId = snapData["Chat id"];

    const docSnapshot = await admin.firestore().collection("chat").doc(chatId).get()

    const data = docSnapshot.data()
    console.log(data)

    const payload = {
      notification: {
        title: userName,
        body: data["Chat message"],
        sound: "default"
      },
      data: {
        click_action: "FLUTTER_NOTIFICATION_CLICK",
        message: "Sample Push Message"
      },
    };

    return await admin.messaging().sendToDevice(tokens, payload);
  });

here is the error::


i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> lint
> eslint .


/Users/juan/StudioProjects/mynotes/functions/index.js
  22:39  error  Parsing error: Unexpected token =>

✖ 1 problem (1 error, 0 warnings)


Error: functions predeploy error: Command terminated with non-zero exit code 1

Having trouble? Try firebase [command] --help
juan@juans-Air mynotes % firebase [command] --help
zsh: no matches found: [command]
juan@juans-Air mynotes % firebase [command] --help
zsh: no matches found: [command]
juan@juans-Air mynotes % (cd functions && npx eslint . --fix)
firebase deploy

/Users/juan/StudioProjects/mynotes/functions/index.js
  22:39  error  Parsing error: Unexpected token =>

✖ 1 problem (1 error, 0 warnings)


=== Deploying to 'mynotes-b58d2'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> lint
> eslint .


/Users/juan/StudioProjects/mynotes/functions/index.js
  22:39  error  Parsing error: Unexpected token =>

✖ 1 problem (1 error, 0 warnings)


Error: functions predeploy error: Command terminated with non-zero exit code 1

Having trouble? Try firebase [command] --help
juan@juans-Air mynotes % 

here is a pic

error pic

CodePudding user response:

  1. The code in then() will execute once the promise returned by get() has resolved. However, the code still continues and hence the logged value is a an unresolved Promise.
  2. The sendToDevice() function also returns a promise so you must handle that as well.
  3. You must return a promise to terminate background Cloud Function or you might get a timeout error.

Try refactoring the code as shown below:

exports.onChatMessageCreate = functions.firestore
  .document("chat messages/{docId}")
  .onCreate(async (snapshot, context) => {
    const snapData = snapshot.data();
    const userName = snapData["userName"];
    // fetch user to send message to
    const chatId = snapData["Chat id"];

    const docSnapshot = await admin.firestore().collection("chat").doc(chatId).get()

    const data = docSnapshot.data()
    console.log(data)

    const payload = {
      notification: {
        title: userName,
        body: data["Chat message"],
        sound: "default"
      },
      data: {
        click_action: "FLUTTER_NOTIFICATION_CLICK",
        message: "Sample Push Message"
      },
    };

    return await admin.messaging().sendToDevice(tokens, payload);
  });
  • Related