Skip to content
Advertisement

How to access field on an array in cloud function?

I have this cloud function that creates a new document every time I have a new chat. I am trying to access the values on the messages array, but I got undefined on the console log.

here is my document on firebase:

enter image description here

I am trying to access the messages with lastMessage = data.messages to create a new document with these values on my function:

exports.onConversationCreated = functions.firestore.document('chat/{chatId}')
.onCreate((snapshot, context) => {
  let data = snapshot.data();
  let chatId = context.params.chatId;

 if(data){
    let members = data.members;
    let lastMessage = data.messages;
    for(let index = 0; index < members.length; index++){
        let currentUserId = members[index];
        let remainingUsersId = members.filter((u) => u != currentUserId);
        console.log(lastMessage.message);
        remainingUsersId.forEach((m) => {
            return admin.firestore().collection('authUsers').doc(m).get().then( (_doc) => {
                let userData = _doc.data();
                if(userData) {

                    return admin.firestore().collection("authUsers")
                    .doc(currentUserId).collection('chat').doc(m).create({
                        "chatId": chatId,
                        "image": userData.photoUrl,
                        "name": userData.displayName,
                        "unseenCount": 0,
                        "lastMessage": lastMessage.message,
                        "timestamp": lastMessage.timestamp,
                        "type": lastMessage.type
                    });
                }
                return null;

            }).catch(() => {return null});
        })
    }
  }
  return null;
});

I am trying to access the value message which is in the messages array, but I get undefined on the console log, do you guys know how I can access it?

Advertisement

Answer

This is because the messages field is an Array with one element, exactly like the members field is an Array with two elements. We can see that from the screenshot of your Firestore database: members has two elements (of type String), indexed with 0 and 1, and messages has one element (of type Map), indexed with 0.

You therefore need to access it as follows:

let lastMessage = data.messages;
//....
console.log(lastMessage[0].message);

It is not clear, from the content of your question, if there is any specific reason for defining the messages field as an Array. Are there any cases when you have several elements? If no, you should probably directly save the messages data as a Map.


In addition, note that you are incorrectly managing the life cycle of your Cloud Function. You should return a Promise when all the asynchronous work is completed. See the doc for more details.

Since you are executing a variable number of calls to Firebase asynchronous methods in a forEach loop, you should use Promise.all().

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement