web-dev-qa-db-fra.com

Firebase child_added pour les nouveaux éléments uniquement

J'utilise Firebase et Node avec Redux. Je charge tous les objets d'une clé comme suit.

firebaseDb.child('invites').on('child_added', snapshot => {
})

L'idée derrière cette méthode est que nous obtenons une charge utile de la base de données et n'utilisons qu'une seule action pour mettre à jour mes bases de données locales via les réducteurs.

Ensuite, je dois écouter tous les enfants NEW ou MIS À JOUR de l'invite clé . Le problème, toutefois, est que l'événement child_added déclenche tous clés existantes, ainsi que celles nouvellement ajoutées. Je ne veux pas ce comportement, je n'ai besoin que de nouvelles clés, car les données existantes ont été récupérées. 

Je suis conscient que child_added est généralement utilisé pour ce type d'opération. Cependant, je souhaite réduire le nombre d'actions déclenchées et restituer le résultat.

Quel serait le meilleur modèle pour atteindre cet objectif? 

Merci,

18
Lee

J'ai résolu le problème en utilisant la méthode suivante. 

firebaseDb.child('invites').limitToLast(1).on('child_added', cb)
firebaseDb.child('invites').on('child_changed', cb)

limitToLast (1) récupère le dernier objet enfant des invitations, puis en écoute les nouveaux, en transmettant un objet instantané au rappel cb.

child_changed écoute toutes les mises à jour des enfants sur invitation, transmettant un instantané au cb

16
Lee

Bien que la méthode limite soit assez bonne et efficace, vous devez néanmoins ajouter un contrôle au child_added pour le dernier élément à récupérer. De plus, je ne sais pas si c'est toujours le cas, mais vous pouvez obtenir les "anciens" événements d'éléments précédemment supprimés, de sorte que vous devrez peut-être également regarder cela.

Les autres solutions seraient soit:

Utilisez un booléen qui empêchera les anciens objets ajoutés d'appeler le rappel

let newItems = false

firebaseDb.child('invites').on('child_added', snapshot => {
  if (!newItems) { return }
  // do
})

firebaseDb.child('invites').once('value', () => {
  newItems = true
})

L’inconvénient de cette méthode est qu’elle impliquerait d’obtenir des événements qui ne feront rien mais vous aurez peut-être un problème si vous avez une grande liste initiale.

Ou si vous avez un horodatage sur vos invitations, faites quelque chose comme

firebaseDb.child('invites')
  .orderByChild('timestamp')
  .startAt(Date.now())
  .on('child_added', snapshot => {
  // do
})
13
Balthazar

J'ai résolu ce problème en ignorant child_added tous ensemble et en utilisant simplement child_changed. Pour ce faire, j'ai utilisé une update() sur tous les éléments que je devais gérer après / en les plaçant dans la base de données. Cette solution dépendra de vos besoins, mais un exemple consiste à mettre à jour une clé d’horodatage chaque fois que vous souhaitez que l’événement soit déclenché. Par exemple:

var newObj = { ... }
// Push the new item with no events
fb.Push(newObj)
// update a timestamp key on the item to trigger child_changed
fb.update({ updated: yourTimeStamp })
0
Matt Way