Joseph Beuys' Mum
Joseph Beuys' Mum

Reputation: 2284

How does one get an async React function calling firebase.firestore.set to wait whilst using an onSnapshot callback?

Here is [a simplified version] of my current code:

export const setTimestamp = async () => {
    console.log("START")
    let result = null;
    const dbRef = await firestore.collection("collectionName").doc("docName");
    const unsub = await dbRef.onSnapshot(snap => {
        result = snap.data();
        console.log("ACTUAL END", result);
    });
    await dbRef.set({ serverTime: firebase.firestore.FieldValue.serverTimestamp() });
    unsub();
    console.log("FUNCTION END", result);
    return result;
};

FUNCTION END is currently logged before ACTUAL END whilst I need it the other way around. Any ideas? Are there perhaps alternatives to using onSnapshot?

Thank you for reading.

Upvotes: 1

Views: 373

Answers (2)

Joseph Beuys' Mum
Joseph Beuys' Mum

Reputation: 2284

@Eldar's answer is correct but I subsequently found and prefer this approach:

import { v4 as UUID } from "uuid";

export const setTimestamp = async () => {
    let result = null;
    const dbRef = firestore.collection("collectionName").doc(UUID());
    await bdRef.set({ serverTime: firebase.firestore.FieldValue.serverTimestamp() })
        .catch(error => console.log("ERROR", error));
    await dbRef.get()
        .then(value => result = value.data())
        .catch(error => console.log("ERROR", error));
    return result;
};

Upvotes: 0

Eldar
Eldar

Reputation: 10790

Well, onSnapshot is an event that returns a Promise for the subscription. But the event will be fired after subscription. If you want to make sure the event is fired you need another Promise that handles the scenario:

const res = await new Promise( async resolve=> {
const unsub = await dbRef.onSnapshot(snap => {
        result = snap.data();
        
        console.log("ACTUAL END", result);
        resolve({result,unsub});
    });
});

await dbRef.set({ serverTime: firebase.firestore.FieldValue.serverTimestamp() });
res.unsub();
console.log("FUNCTION END", res.result);
return res.result;

Upvotes: 1

Related Questions