4
votes

Cloud Functions for Firestore: accéder aux données de la collection parent

De nombreux blogs suggèrent de passer à Cloud Firestore car c'est facile et bien sécurisé. Venant de la base de données en temps réel et retour lors de l'utilisation de Functions + RD, il était facile de naviguer dans les déclencheurs de document, comme ref.parent

Ma configuration est comme ceci:

  • Utilisateurs
    • {userid}
      • last_seen: "données"
      • {formulaires}
        • {formid}

Cependant, j'ai ajouté un déclencheur de document avec onCreate , et je veux obtenir la valeur de last_seen :

exports.updateUser = functions.firestore.document('users/{userId}/forms/{formid}').onCreate((snap, context) => {

    const newValue = snap.data();
    console.log("test value : " + newValue.test); // works
    console.log("form id: " + context.params.formid); // works
    console.log("user last seen : " + newValue.last_seen); // doesn't work, can't access the parent collection data


});


0 commentaires

3 Réponses :


1
votes

Dans votre code, snap est un Objet de type DocumentSnapshot . Comme vous pouvez le voir dans la documentation de l'API liée, il existe un < code> ref sur cet objet qui vous donne une DocumentReference pointant vers le document qui a été ajouté. Cet objet a parent < / a> qui vous donne une CollectionReference qui pointe vers la collection où se trouve le document, qui a également un Propriété parent . Alors, utilisez ces propriétés pour naviguer dans votre base de données selon vos besoins.


0 commentaires

19
votes

Je comprends totalement la confusion avec le passage à Firestore mais c'est presque exactement la même chose dans ce cas.

En temps réel, vous avez l'instantané:

functions.firestore.document.onCreate('/users/{userId}/forms/{formId}')
    .onCreate(async (snapshot, context) => {
    const userId = context.params.userId;
    const lastSeen = await getLastSeen(userId);
});

// == Helper Functions ==-------------------
export async getLastSeen(userId) {
    if (!userId) return Promise.reject('no userId');
    // User Ref
    const userSnap = await firebaseAdmin.firestore().collection('users').doc(userId).get();
    return userSnap.data().last_seen;
}

Dans Firestore:

functions.firestore.document.onCreate('/users/{userId}/forms/{formId}')
    .onCreate((snapshot, context) => {
    const userId = context.params.userId;
    const userRef = firebaseAdmin.firestore().collection('users').doc(userId);
    userRef.get().then(parentSnap => {
        const user = parentSnap.data();
        const lastSeen = user.last_seen;
    });
});

Une autre chose à considérer est que vous passez le userId dans vos paramètres afin que vous puissiez simplement créer votre propre DocumentReference (en supposant que vous ' vous utilisez également firebaseAdmin)

exports.doStuff = functions.firestore.document.onCreate('/users/{userId}/forms/{formId}')
    .onCreate((snapshot, context) => {
    const ref = snapshot.ref;
    const userRef = ref.parent.parent;
    userRef.get().then(parentSnap => {
        const user = parentSnap.data();
        const lastSeen = user.last_seen;
    });
});

Cela vous permet également de découpler votre logique pour les fonctions que vous pouvez utiliser souvent, considérez-la comme une méthode "d'assistance": (NOTE, je suis passé à async / await en cas d'accident, c'est un peu plus propre)

exports.doStuff = functions.database.ref('/users/{userId}/forms/{formId}')
    .onCreate((snapshot, context) => {
    const ref = snapshot.ref;
    const userRef = ref.parent.parent;
    userRef.once('value').then(parentSnap => {
        const user = parentSnap.val();
        const lastSeen = user.last_seen;
    });
});

Vous pouvez maintenant utiliser getLastSeen () quand vous en avez besoin, et si vous faites un changer, vous n'avez qu'à ajuster cette fonction. Si ce n'est pas quelque chose que vous appelez souvent, ne vous inquiétez pas, mais j'envisagerais peut-être un assistant getUser () ...


1 commentaires

une réponse si claire et concise, merci beaucoup pour les conseils



0
votes

Obtenez la référence où le changement a eu lieu, déplacez-vous de 2 niveaux vers le haut et capturez les données en utilisant la fonction ref.once () :

exports.updateUser = functions.firestore.document('users/{userId}/forms/{formid}').onCreate( async (snap, context) => {

    // Get the reference where the change took place
    const changeRef = snap.after.ref;

    // Move to grandad level (2 levels up)
    const userIdRef = changeRef.parent.parent;

    // Capture data
    const snapshot = await userIdRef.once('value');

    // Get variable
    const lastSeen = snapshot.val().last_seen;

    // Do your stuff...

    return null;

});


0 commentaires