I have a created a chat app using firestore(using angularfire wrapper) and angular and it's working. The database structure is like this. I have unique ids for every user. When ever someone(sender) sends a message to other person(receiver) I add the message to sender:
collection("messages") => doc(sender's ID) => collection(receiver's ID) => doc(message ID)
Also, I add the same message to receiver:
collection("messages") => doc(receiver's ID) => collection(sender's ID) => doc(message ID)
Now, When user(sender) opens a chat with another user(receiver) I attach listener(valueChanges) to:
collection("messages") => doc(sender ID) => collection(receiver ID)
each message in the collection is structured like this:
message: 'string message'
profilePic: 'url for profile pic'
senderId: 'unique id of sender'
timestamp: some timestamp
Everything works as expected with this configurations but there are a few problems.
Using valueChanges
would be simple, but you will see the problems and it also costs of DB usage. So I recommend you to have a look at snapshotChanges.
You could separate the logic as following way.
valuechanges
and first
/or take(1)
operator.this.messages = await this.afs.collection('messages')
.valuechanges()
.pipe(take(1))
.toPromise();
// manage recently added messages
this.afs.collection('messages').snapshotChanges(['added'])
.pipe(takeUntil(untilFn))
.subscribe(added => {
this.messages = [...added, this.messages];
});
// manage recently removed messages
this.afs.collection('messages').snapshotChanges(['removed'])
.pipe(takeUntil(untilFn))
.subscribe(removed => {});
// manage recently modified messages
this.afs.collection('messages').snapshotChanges(['modified'])
.pipe(takeUntil(untilFn))
.subscribe(modified => {});
Please note the return type of snapshotChanges
is different than valueChanges
.