0
votes

I was written a code previous week and it deploys without any error on firebase server. but now I cannot deploy it again on another account in orders to I don't change my code!

one of my friends tell me this in about new update of firebase but I don't find any solution for this!

it shows these errors

Promises must be handled appropriately

and

block is empty

the first error pointed to my first line and the second one pointed to end 'catch' block :

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();

// export const helloWorld = functions.https.onRequest((request, response) => {
//  console.log("sadegh");
//  response.send("Hello from Firebase1!");
// });
//
export const sendChatNotification = functions
.firestore.document('rooms/{roomId}/messages/{messageId}')
.onCreate((snap, context) => {



    const roomId = context.params.roomId;
    const messageId = context.params.messageId;

    const newValue = snap.data();

    const receiverId = newValue.receiverId;
    const text = newValue.text;
    const type = newValue.type;
    const senderName = newValue.senderName;


    var p = admin.firestore().collection("users").doc(receiverId).get();
    p.then(snapshot2 => {
        const data2 = snapshot2.data();
        const firebaseNotificationToken = data2.firebaseNotificationToken;
        // const name = data2.name;

        if (type == 'voiceCall' || type == 'videoCall' || type == 'hangUp') {


            const channelId = newValue.channelId;
            const senderId = newValue.senderId;
            const status = newValue.status;

            console.log("type: " + type + " /status: " + status)

            let message = {
                data: {
                    type: type,
                    senderId: senderId,
                    senderName: senderName,
                    receiverId: receiverId,
                    status: status,
                    channelId: channelId,
                    roomId: roomId
                },
                token: firebaseNotificationToken
            };

            sendMessage(message)


            if (status == "canceled") {
                let message1 = {
                    notification: {
                        title: '☎ Missed voice call ',
                        body: senderName
                    },
                    token: firebaseNotificationToken
                };
                sendMessage(message1)
            } else if ((type == 'voiceCall' || type == 'videoCall') && status = '') {
                let message1 = {
                    notification: {
                        title: '☎ ' + senderName + ' is calling you',
                        body: 'tap to answer...'
                    },
                    token: firebaseNotificationToken
                };
                sendMessage(message1)
            }


        } else {
            let message = {
                notification: {
                    title: '???? ' + senderName,
                    body: text
                },
                token: firebaseNotificationToken
            };


            sendMessage(message)

        }


        return "";
    }).catch((e) => {
        console.log('error: ' + e);
        return null;
    });


    //       return "";
    // }).catch(e=>{console.log('error: '+e)});


    return "sadegh";
});

function sendMessage(message) {
    admin.messaging().send(message)
        .then((response) => {
            // Response is a message ID string.
            console.log('Successfully sent message:', response);
        })
        .catch((error) => {
            console.log('Error sending message:', error);
        });
}
2
Could you include in your question the full code of your Cloud Function? Most probably your problem comes form the fact that, among others, you don't return the promise returned by admin.firestore().collection("users").doc(receiverId).get()but we need the full (i.e. entire) code to confirm this assumption.Renaud Tarnec
@RenaudTarnec full code added. thanks for reviewSadegh
Thanks for the addition. To be frank, your code is a bit messy and it is not really easy to understand it without dedicating a long time... However, here is below in my answer a piece of code that should work and that cover one case of your Business Logic. If you modify your code on the base on this first example, I'll will be happy to look at it again.Renaud Tarnec

2 Answers

2
votes

Your code is a bit messy and it is not really easy to understand it without dedicating a long time.

However, here is below a piece of code that should work and that cover one case of your Business Logic. Note how the promises returned by the asynchronous tasks are returned.

  export const sendChatNotification = functions.firestore
      .document('rooms/{roomId}/messages/{messageId}')
      .onCreate((snap, context) => {
        const roomId = context.params.roomId;
        const messageId = context.params.messageId;

        const newValue = snap.data();

        const receiverId = newValue.receiverId;
        const text = newValue.text;
        const type = newValue.type;
        const senderName = newValue.senderName;

        var p = admin
          .firestore()
          .collection('users')
          .doc(receiverId)
          .get();

        return p.then(snapshot2 => {  // <- HERE, the promise is returned
          const data2 = snapshot2.data();
          const firebaseNotificationToken = data2.firebaseNotificationToken;

          if (type == 'voiceCall' || type == 'videoCall' || type == 'hangUp') {
            const channelId = newValue.channelId;
            const senderId = newValue.senderId;
            const status = newValue.status;

            console.log('type: ' + type + ' /status: ' + status);

            let message = {
              data: {
                type: type,
                senderId: senderId,
                senderName: senderName,
                receiverId: receiverId,
                status: status,
                channelId: channelId,
                roomId: roomId
              },
              token: firebaseNotificationToken
            };

            return admin.messaging().send(message);  // <- HERE, the promise is returned
          }
        });

  }); 

I would suggest you watch the 3 videos about "JavaScript Promises" from the Firebase video series: https://firebase.google.com/docs/functions/video-series/

0
votes

The problem is you commented the return in your catch block As your Firebase .get() function must return a promise, in your code, if it fails, it won't return a promise and it will hang there.

either use return null or return something to be handled by the calling app