Reputation: 2422
I have a very simple chat app. Upon submit, it updates the database with the username and the message.
this.ref.child("/chat").update({username: this.state.username,
message: this.state.chatMessage});
I then use a ref.on('value',()) to get the new chat and store it in an array.
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]})
})
I was trying to think of a workaround to getting duplicate messages (i.e. typing the same message again, since the listener is not triggered if nothing changes) so I though I'd add a date object to the database. When I added the date to the database using
let d = new Date();
this.ref.child("/chat").update({username: this.state.username,
message: this.state.chatMessage, time: d});
The event listener started being triggered twice when I wrote something and submitted it. The user that submitted the chat would get the same message twice and the other user would get it just once. Removing the date fixed the issue.
Does anyone know why this would happen?
Upvotes: 0
Views: 1248
Reputation: 598728
The Firebase Database stored JSON, and Date
isn't a valid JSON type. The idiomatic approach is to store a timestamp:
this.ref.child("/chat").update({username: this.state.username,
message: this.state.chatMessage, time: Date.now()});
Upvotes: 1
Reputation: 823
The reason the on(value, () => {})
listener is triggered twice is that it operates by first fetching and returning the current value, and is then triggered for every subsequent database entry change - if all you want to do is fetch the current value, then you can use the method as described by @Peter Haddad .
Something that is useful to note, is that Firebase guarrantees the following, as seen in their documentation:
Value events are always triggered last and are guaranteed to contain updates from any other events which occurred before that snapshot was taken.
This means that if you call once(value, () => {})
after your call to update the database entry, you are guarranteed that the update has occured and the data returned in the listener includes the updates.
Upvotes: 0
Reputation: 80914
Change this:
this.chat.on('value',(snapshot) => {
into this:
this.chat.once('value').then((snapshot)=> {
This is way it will only b triggered once, more info here:
https://firebase.google.com/docs/database/web/read-and-write#read_data_once
Upvotes: 0