2017-04-26 2 views
0

Angesichts der folgenden Struktur, wie gehe ich zum Abrufen bestimmter Benutzerbenachrichtigungen?Firebase-Datenbank: Abfrage denormalized Datenkämpfe

dh: uid0001 der Lage sein, shoud eine Liste abzurufen: [xxxxx01, xxxxx02]:

notifications 
    uid01 
    xxxxx01 
    uid02 
    xxxxx02 
    uid03 
    xxxxx03 
    uid04 
    xxxxx04 
users 
    uid0001 
    notifications 
     uid01 
     uid02 

Leider ist diese Ungeheuerlichkeit extrem ineffizient:

firebase.database().ref(`users/${user.userId}/notifications`).once('value').then((snapshot) => { 
    snapshot.forEach((data) => { 
    firebase.database().ref(`notifications/${data.key}`).once('value').then((snap) => { 
     this.list.unshift(localUpdates) 
    }) 
    }) 
}) 

Möglicherweise etwas entlang der Linien von (Warnung, Pseudo-Code kommt):

firebase.database().ref('notifications').on('child_added').equalTo('whatever the childs key is here').then((snapshot) => { 

}) 

Wie immer Jede Richtung, Prost und verfaulte Früchte sind willkommen, also danke!

Antwort

1

Es gibt eine Reihe von Lösungen; hier ist zwei (die Pseudo-Code vergeben, wie ich weiß, Ihre Plattform nicht)

die OK-Weg

Ihre bestehende Struktur verwenden, erfassen die untergeordneten Knoten in/users/uid0001/notifications dann diese Kinder durchlaufen, Lesen die Kinder im Benachrichtigungsknoten nacheinander.

Der bessere Weg

notifications 
    -yisijaoijsijdasd //generated by push() or childByAutoId() 
    for_user: "uid01" 
    notification: "Check this out" 
    timestamp: "20170421" 
    user_time: "uid01_20170421" //concatenated allows queries by > 1 item 
    -Y9s90kas9dkka9s 
    for_user: uid01 
    notification: "Yipee" 
    timestamp: "20170426" 
    user_time: "uid01_20170426" 

users 
    uid0001 

abfragen dann die Benachrichtigungen Knoten für:

alle Benachrichtigungen für uid01

notificationsRef.queryOrdered(byChild: "for_user").equalTo("uid01") 

alle Benachrichtigungen für uid01 für die letzten 4 Tage

notificationsRef.queryOrdered(byChild: "user_time") 
       .startingAt("uid01_20170422") 
       .endingAt("uid01_20170426") 

Sie auf diese erweitern könnten - zum Beispiel, wenn Sie den Überblick über die Meldungen halten wollte, die nicht gelesen haben, könnten Sie

notifications 
    -yisijaoijsijdasd //generated by push() or childByAutoId() 
    for_user: "uid01" 
    notification: "Check this out" 
    timestamp: "20170421" 
    user_time: "uid01_20170421" 
    was_read: false 
    user_read: "uid01_false" 

und Abfrage für

notificationsRef.queryOrdered(byChild: "user_read").equalTo("uid01_false") 
+0

Dieses etwas, das ich gewesen hinzufügen haben Nachsinnen. Der 'for_user' müsste ein Array sein. Könnte das 'queryOrdered' noch funktionieren wie ein any? Zum Beispiel: '' 'queryOdered (byChild:" for_user "). Enthält (" uid01 ")' '' – studiobrain

+1

@studiobrain Nein. Bitte verwenden oder speichern Sie keine Arrays in Firebase! Siehe [Array's Are Evil] (https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html). Mit der Struktur, die ich vorschlage, gibt es keinen Grund, Arrays trotzdem zu verwenden. In Firebase gibt es keine "Enthält". Aus diesem Grund habe ich Optionen in meine Lösung aufgenommen, sodass Sie Daten auf verschiedene Arten abfragen können. – Jay

+0

Einverstanden, das war nicht als Literal zu Array so viel wie nur eine Liste gemeint. Das oben genannte funktioniert gut, ich gehe nur eine Ebene tiefer, um die zugehörige Benachrichtigung basierend auf Benutzer zu erhalten ... Danke! – studiobrain