Search code examples
javascriptfirebasegoogle-cloud-firestore

How do I update a collection inside a firestore document?


I am trying to create a chat between users and me for customer support purposes, to do this I want to have it so that the login users can go to the contact page they can type in their message and hit send which will update a new document containing their message as well as a timestamp.

  setup(){
      const { Chat, error, load } = getChat();
      load();
    const message = ref('')
    const Activate = ref(false)
    const handleSubmit = async () => {  
    const NewChat = {
        message: message.value,
        createdAt: timestamp(),
    }
    const res = await projectFirestore.collection('Subscribed').doc(firebaseAuth.currentUser.uid).collection('messages').doc().update(NewChat)
  }
  return { handleSubmit, Activate, message, Chat, load }
}

As you can see above the location that I want this to be updated in is within the 'Subscribed' collection inside the document with the users UID, which is then inside the collection 'messages' where I want to add a new document with the message and the UID inside them each time they type and send the message.

The error I am getting is

enter image description here

I don't understand why this happens because I have done other updates like this before the only difference being the update occurs inside the UID document and I do not have to reach down into the next collection so I assume the problem is reaching into the collection with in the document. I had a similar problem retrieving the data within the messages collection to display for the messages too but I was able to get around this by writing the following code into a JavaScript document and then importing the data onto the messages page.

import { projectFirestore } from "../Firebase/Config";
import { ref } from "vue"
import { firebaseAuth } from "../Firebase/firebase";

const getChat = () => {
    const Chat = ref([])
    const error = ref(null)
    let lastDoc = null; 

    const load = async () => {
        try {
            let query = projectFirestore.collection('Subscribed').doc(firebaseAuth.currentUser.uid).collection('messages').orderBy('createdAt')
            if (lastDoc) {
                query = query.startAfter(lastDoc)
            }

            const res = await query.get()

            if (!res.empty) {
                lastDoc = res.docs[res.docs.length - 1]

                // Add new results to exsiting ones

                Chat.value = [...Chat.value, ...res.docs.map(doc => {
                  //  console.log(doc.data())
                    return {...doc.data(), id: doc.id}
                })]
            }
        }
        catch (err){
            error.value = err.message
           // console.log(error.value)
        }
    }

    return { Chat, error, load }
}

export default getChat

I was then able to successfully display the messages collections messages on the page I imported it to, but I am unable to do that here for the update because I am not after what is in the collection but I need to specify the path to update inside of the collection.

I do need the document to be added within the messages collection. Does anyone have any ideas how to make this update function work and update the messages collection inside the document?


Solution

  • This will never work:

    ....collection('messages').doc().update(NewChat)
    

    Calling doc() (without any arguments) creates a reference to a new, non-existing document, and you can only call update for an existing document.


    You also can't call update on a collection. A collection is nothing more than a container for the documents in it. So you can update a document, but not a collection.


    If you want to add a new message document to the messages collection, you can do that by calling add:

    ...collection('messages').add(NewChat)
    

    I recommend keeping the Firebase documentation handy, as this is covered in the section on adding a document to a collection.