2

I'm building a simple chat application using Firebase and Firestore. The pseudo-schema I have in my mind looks like this:

• threads: collection
  |
  +---- • friend_id: str
        • last_messaged: timestamp
        • messages: collection
          |
          +---- • sender_id: str
                • text: str
                • timestamp: timestamp

Now, lets say my friend with an id of 420 messages me for the first time. I would want to store this data by creating a new thread. Lets say I do this using the following command:

const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var db = admin.firestore();

var thread_id = '212';
var message_id = '3498213712';

db.collection('threads').add({
    id: thread_id,
    friend_id: '420',
    last_messaged: 1557862539,
    messages: [
        {
            id: message_id,
            sender_id: '420',
            text: 'Hello',
            timestamp: 1557862539
        }
    ]
})

Is this the right way to do things? Would a collection called messages be automatically created since I'm sending a JSON object in that field? If not, how can I do this the right way?

EDIT: Perhaps I was not clear enough earlier. I want messages to be a sub-collection. Right now, it is an array, according to a comment below.

EDIT2: Both threads id and messages are not random. Update the code to reflect that.

NOT DUPLICATE: Not a duplicate of the question linked in the comments because that question is for Java and the Android SDK, while this one is for Javascript.

darkhorse
  • 8,192
  • 21
  • 72
  • 148
  • That will create an array field on the thread document. – Herohtar May 14 '19 at 19:48
  • @Herohtar - Would you please write an answer explaining how? – darkhorse May 14 '19 at 19:50
  • What's wrong with your proposed solution? Is something not working the way you expect? – Doug Stevenson May 14 '19 at 19:55
  • @DougStevenson I specifically mentioned in the schema that `messages` have to be a collection. The code that I wrote creates an array field according to Herothar's comment. – darkhorse May 14 '19 at 19:58
  • Possible duplicate of [How to add subcollection to a document in Firebase Cloud Firestore](https://stackoverflow.com/questions/47514419/how-to-add-subcollection-to-a-document-in-firebase-cloud-firestore) – Herohtar May 14 '19 at 20:06
  • @DougStevenson Everything is not working fine, because as I keep repeating, I want `messages` to be a collection. Right now, it is an array. I apologize if I am missing something obvious. – darkhorse May 14 '19 at 20:14
  • You've called your collection "threads" in your code. Are you saying you want "messages" to be subcollection under a document in "threads"? – Doug Stevenson May 14 '19 at 20:15
  • @DougStevenson Yes, sorry I was not aware of the sub-collection terminology. – darkhorse May 14 '19 at 20:16
  • You will have to decide what you want your document ID to be for the document in the "messages" subcollection. Do you have a document ID in mind, or do you want a random ID? Please be specific about what you intend the final result to be. – Doug Stevenson May 14 '19 at 20:18
  • @DougStevenson - Not random. Updated the code to reflect that, but I'm pretty sure the id needs to be set some other way, but hopefully, the idea is clear now. – darkhorse May 14 '19 at 20:22
  • Sorry, didn't look closely enough at the question. Try [this one](https://stackoverflow.com/questions/48873465/how-to-add-sub-collection-to-a-document-in-firestore). Although the other one is for Java, the format of the document/collection syntax is very similar so it's a good reference anyway. – Herohtar May 14 '19 at 20:24
  • You should know that your first document added is getting a random id. This is what `add()` does. Is that also what you wanted, given that you also have a specific thread id? There is a big difference between the formal document ID recognized by Firestore, and a field called "id". They are not the same. – Doug Stevenson May 14 '19 at 20:25
  • @DougStevenson As I mentioned in the question, not random. Clearly I made an error in my code in the question, hence the existence of this question. The `thread_id` and `message_id` need to be the formal document IDs, but I don't know how to set them. – darkhorse May 14 '19 at 20:27

1 Answers1

1

You should be building a reference to the document, then creating its contents using set() on that reference instead of add() (since add always creates a new random document id). This is detailed in the documentation, which I strongly recommend studuing in order to understand how Firestore works. You will use that information a lot.

To create a document with a known ID (in the variable thread_id) in a top level document:

db.collection('threads').doc(thread_id).set({
    friend_id: '420',
    last_messaged: 1557862539
})

To create a document with a known ID in a subcollection, it's exactly the same, except you have to put the name of the subcollection in the path of the document reference:

db.collection('threads').doc(thread_id).collection('messages').doc(message_id).set({
    sender_id: '420',
    text: 'Hello',
    timestamp: 1557862539
})
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441