Taha Azzabi
Taha Azzabi

Reputation: 2570

Await query Realtime Updates and then return value [Vuex ,Firestore]

I’m trying to wait the data from a Firestore real time query, and then perform other actions.. Everything works as expected and I do have the data form firebase as Object, but when I’ve tried to get the proprieties from the returned Object I have an empty result

Vuex Action

export const getThreadMembers = async ({ commit,dispatch }, payload) => {
      try {
        let members = {}
        const threadMembersRef = await db.collection('members')
                                  .doc(payload.threadId)

        threadMembersRef.onSnapshot(function(doc) {
          Object.assign(members,doc.data())
        })   
        /*
         * I've tried to add some delay before resolve the promise , i've succeeded to have the properties names of member Object
         *await dispatch('delay', 5000);
         */
        return Promise.resolve(members)
      } catch (error) {
        return  Promise.reject(error)
      }
    }
/*
 * this is a function for test purpose only
 */ 
export const delay = ({commit}) => {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(42); // After 3 seconds, resolve the promise with value 42
    }, 3000);
  });
}

Component file

      created () {
        this.getThreadMembers({
          threadId: this.threadId
        }).then(members => {
          // Here the Members value is an object
          //{bUNFP8ylLpSvZVdIUyOypQ9WfMB3: truej9R1VgexbZU2yp5q5icnIcIg5xB3: true__proto__: Object}
          console.log(members)
          // When i've tried to get only the key of members Object is always empty !?
          console.log(Object.getOwnPropertyNames(members))
         //[]length: 0__proto__: Array(0)

        })
      }

Question:

Why Object.getOwnPropertyNames(members) is executed before members ?

Upvotes: 1

Views: 1364

Answers (1)

Jen Person
Jen Person

Reputation: 7546

The work of onSnapshot is asynchronous, but right now it's not being handled, so the rest of the function just continues without waiting for that promise to resolve. Using await is one way to solve this problem.

    const doc = await threadMembersRef.onSnapshot()
    Object.assign(members,doc.data())

Also you don't need to use await on threadMembersRef because it's just assigning a reference, not doing any work.

const threadMembersRef = db.collection('members')
                              .doc(payload.threadId)

Upvotes: 2

Related Questions