0
votes

I am using a scheduled task in a Firebase Cloud Function to query an array which contains a number of objects that need to be updated if a matching condition exists. My current attempt is using the 'array-contains' method to get the objects, then loop over them to find a matching condition which will then batch update the items. This is my data structure:

enter image description here

I need to find an object that is <= the current time, and also if the 'active' value = false.

export const liveMeetingsTrigger = functions.runWith( { memory: '1GB' }).pubsub

    .schedule('every 1 minutes').onRun(async context => {

        const now = admin.firestore.Timestamp.now();

        const liveMeetings = await admin.firestore().collection('fl_content').where('meeting', 'array-contains', 'liveMeetingDate').get();

        const batch = admin.firestore().batch();
        
        liveMeetings.forEach(doc => {

          if(doc.data().liveMeetingDate <= now && doc.data().active == false){
             batch.update(doc.ref,'active',true);
          }

        });
        
        return await batch.commit();

});

I have also tried using an exact object in the query instead of just using 'liveMeetingDate', but still get no results back, any help would be great - thanks.

Debugging: As the array I am trying to reach is inside of the (map) object 'liveMeetings' i have tried the dot notation (liveMeetings.meeting) with no success. Also trying a new collection with the the 'meeting' array at top level has provided no success.

Simple logging in the console (liveMeetings.size) shows that nothing is being returned on the query, so therefore the logging does not even reach the loop in the code.

enter image description here

1
you want to compare date with current time ?Ashish
@Ashish Yes I am comparing the date in 'liveMeetingDate' in the object with the server timestamp. I think the first problem is on the query as when I log any results it dies not event reach the loop.dbach
Meeting is subpart of liveMeetings map so it's impossible to query.Ashish
@Ashish so you are saying the the 'meetings' array needs to be top level and not nested inside of an object (Map type)?dbach
if you want to compare dates then you need array on top levelAshish

1 Answers

1
votes

As explained in this anwser the following query will not work:

const liveMeetings = await admin.firestore().collection('fl_content').where('meeting', 'array-contains', 'liveMeetingDate').get();

because the meetings array contain some objects, instead of "simple" or primitive data (e.g. string, number...).

You could query it with the exact objects, like:

const obj = {active: false, liveMeetingDate: ..., meetingId: ..., ....};
    const liveMeetings = await admin.firestore().collection('fl_content').where('meeting', 'array-contains', 'obj').get();

Another approach would be to create a new collection which contains the similar documents (same Document ID) but with a meeting Array that contains only the liveMeetingDate property.


Finally, note that since your Array is within a map, you need to do

await admin.firestore().collection('fl_content').where('liveMeetings.meeting', 'array-contains', ...).get();

(PS: I don't mark this question as duplicate since you expressly ask for more help in the comments of the duplicate question/answer)