Angular FireStore Collections inside Documents

Angular FireStore Collections inside Documents

I am trying to build a chat app in Angular 2, using Firebase FireStore Database.
I was able to create one Collection, with a Docuement for each 'message'. 
I used this code to retrieve the messages:
export interface MessageItem {
  message: string;
  DateTime: Date;
  User: string;

messagesCollection: AngularFirestoreCollection;
messages: Observable;

getChatData() {
  this.messagesCollection = this.afs.collection('chat_messages');
  this.messages = this.messagesCollection.valueChanges();

However, because I want multiple users, I would like to create a Document for each user, which stores inside a Collection of the messages.
This complicates it, and I'm not sure how to do it exactly.
I would be happy for some guidance.


Solution 1:

A route you may be able to take is instead of storing the collection of documents as ‘Messages’ you would want to create a collection of ‘Conversations’ and in each ‘Conversation’ document then have a simple array of ‘DocumentReferences’ that reference the two users in that conversation. You could also just store the UID’s of each user and then fetch the user if necessary. Then, inside of the ‘Conversation’ document you would have a collection of messages between the two users. This is an approach I would take and if you need more assistance I can create the mockup service and data structure to show as an example. In short, storing the conversations first will help with the structure here.

Here is an example of how I would set up Firestore structure:

enter image description here

Here in the conversations collection I would store an Array of DocumentReferences to the users and then have a collection of Messages related to this conversation.

enter image description here

Now here in the users collection I would have a document for each user, where the Document Id is the UID from the authenticated User. This may seem redundant but I would also create a conversations collection in the user collection where each document only has a one field which is a DocumentReference to the conversation document. Here is an example of that document in the convos collection:

enter image description here

This way you stop users from being able to create duplicate conversation documents inside of the Conversations collection and you just need to make sure you save the conversation reference to each users convos collection after the conversation has been started.

When fetching the data from a service you would need to then snapshotChanges and grab that reference path and then request the conversation inside of your map function on the snapshot. Please let me know if you need guidance with the service after you have created this and setup your service with angularfire2.

Solution 2:

There’s a lot of ways to go, but this Build A Real-Time Chat App With VueJS, Vuex & Cloud Firestore shows a fairly good implementation in vue.

This is their conversation document.

Conversation structure

  users: ['mr_a', 'mr_b'],
  messages: [
    { id: uuidv4(), text: 'Hi there', sender: 'mr_a', created: },
    { id: uuidv4(), text: 'Hi to you too!', sender: 'mr_b', created: }

For the mechanics of AngularFire2, see Simple Chat App with AngularFire2 (Firebase + Angular 2). It uses one conversation with messages as documents.