J'ai une application de chat très simple. Lors de la soumission, il met à jour la base de données avec le nom d'utilisateur et le message.

this.ref.child("/chat").update({username: this.state.username, 
    message: this.state.chatMessage});

J'utilise ensuite un ref.on ('value', ()) pour obtenir le nouveau chat et le stocker dans un tableau.

this.chat.on('value',(snapshot) => {
    console.log('triggered')
    let newMessage = {username:snapshot.val().username, message: snapshot.val().message}
    this.setState({chatArray: [...this.state.chatArray,newMessage]})
}) 

J'essayais de penser à une solution de contournement pour obtenir des messages en double (c'est-à-dire taper à nouveau le même message, car l'écouteur n'est pas déclenché si rien ne change), alors j'ai pensé ajouter un objet date à la base de données. Quand j'ai ajouté la date à la base de données en utilisant

let d = new Date();
this.ref.child("/chat").update({username: this.state.username, 
    message: this.state.chatMessage, time: d});

L'auditeur d'événements a commencé à être déclenché deux fois lorsque j'ai écrit quelque chose et que je l'ai soumis. L'utilisateur qui a soumis le chat recevrait le même message deux fois et l'autre utilisateur ne le recevrait qu'une seule fois. La suppression de la date a résolu le problème.

Est-ce que quelqu'un sait pourquoi cela se produirait?

0
WebbH 11 avril 2018 à 16:54

3 réponses

Meilleure réponse

La base de données Firebase stockait du JSON et Date n'est pas un type JSON valide. L'approche idiomatique consiste à stocker un horodatage:

this.ref.child("/chat").update({username: this.state.username, 
    message: this.state.chatMessage, time: Date.now()});
1
André Kool 11 avril 2018 à 14:17

La raison pour laquelle l'écouteur on(value, () => {}) est déclenché deux fois est qu'il fonctionne en récupérant d'abord et en renvoyant la valeur actuelle, puis est déclenché pour chaque modification d'entrée de base de données suivante - si tout ce que vous voulez faire est récupérer la valeur actuelle, alors vous peut utiliser la méthode décrite par @Peter Haddad.

Il est utile de noter que Firebase garantit les éléments suivants, comme indiqué dans leur documentation:

Les événements de valeur sont toujours déclenchés en dernier et sont garantis pour contenir les mises à jour de tout autre événement qui s'est produit avant la prise de cet instantané.

Cela signifie que si vous appelez once(value, () => {}) après votre appel pour mettre à jour l'entrée de base de données, vous êtes assuré que la mise à jour s'est produite et que les données renvoyées dans l'écouteur incluent les mises à jour.

0
YodaScholtz 11 avril 2018 à 14:12

Change ça:

this.chat.on('value',(snapshot) => {

En cela:

this.chat.once('value').then((snapshot)=> {

C'est ainsi qu'il ne se déclenchera qu'une seule fois, plus d'informations ici:

https://firebase.google.com/docs/database/web/read-and-write#read_data_once

0
Peter Haddad 11 avril 2018 à 13:58