Nativescript-plugin-firebase: Adding a document to a subcollection of a collection in Firestore

Created on 6 Mar 2019  路  6Comments  路  Source: EddyVerbruggen/nativescript-plugin-firebase

Apologies if I am doing something wrong, but I am not sure if this is an issue with the plugin or not.

I have documents in a "message" collection. I have manually added a "comments" sub-collection to some of those documents through the web ui, and tried the below code on both documents with and without that existing sub-collection added.

The code that I'm having trouble with looks like this:

this.messageRef = firebase.firestore.collection('messages').doc(this.message_id);

this.messageRef.collection("comments").add({
                    comment: this.commentToAdd,
                    created_at: new Date()
                })
                    .then(function (docRef) {
                        // ..
                    })
                    .catch(function (error) {
                        console.error("Error adding document: ", error);
                    });

I am getting this error:

JS ERROR TypeError: this.messageRef.collection is not a function. (In 'this.messageRef.collection("comments")', 'this.messageRef.collection' is undefined)

Am I using an incorrect object or something? Surprisingly I can find so little help on this issue through my usual google-fu, so maybe this question will help someone else.

Thanks.

Most helpful comment

Yes! You are right, this works perfectly both for adding to a subcollection and getting the documents in a subcollection. I have to admit that I didn't know that there was a distinction between the Web API and whatever I was using. What was I using, and any direction on when to use one vs the other?

For the record, as you know, I was incorrectly doing it like this:

import firebase from "nativescript-plugin-firebase";

this.messageRef = firebase.firestore.collection('messages').doc(this.message_id);

this.messageRef.collection("comments").add({ ...

Whereas it needed to be

const firebase = require("nativescript-plugin-firebase/app");

this.messageRef = firebase.firestore().collection('messages').doc(this.message_id);

Then I was able to chain a collection onto it.

THANK YOU.

All 6 comments

Hi, if you search for .doc here, you'll see a lot of examples (use .get on the doc reference, not collection).

Thanks, I have looked here, but don't see any examples specific to adding a document to a sub-collection of a collection. I don't have any issues adding a document to a collection, and can add a message to messages, but not a comment to messages.comments.

I think this is what you're suggesting, by using get on the doc reference?

this.messageRef = firebase.firestore.collection('messages').doc(this.message_id);

this.messageRef.get().then(function (doc) {

    // this shows field values, but not the nested sub-collection
    console.log(doc.data());

    // This will Error adding document:  
    // TypeError: doc.collection is not a function. (In 'doc.collection("comments")', 'doc.collection' is undefined)

    doc.collection("comments").add({
        comment: this.commentToAdd,
        created_at: new Date()
    })
    .then(function () {
        // ...
    })
    .catch(function (error) {
    console.error("Error adding document: ", error);
});
})
.catch(function (error) {
    console.error("Error getting document: ", error);
});

I am new to Firestore and could be missing something totally basic here, but I've reached a dead end, and think I am doing what the Firestore doc suggests.

https://firebase.google.com/docs/firestore/data-model#subcollections

Thanks for those details, @mmccaff! I'm trying to stay as close to the Web API as possible, so I'll look into being able to use something like ar messageRef = db.collection('rooms').doc('roomA').collection('messages').doc('message1').

Yes! You are right, this works perfectly both for adding to a subcollection and getting the documents in a subcollection. I have to admit that I didn't know that there was a distinction between the Web API and whatever I was using. What was I using, and any direction on when to use one vs the other?

For the record, as you know, I was incorrectly doing it like this:

import firebase from "nativescript-plugin-firebase";

this.messageRef = firebase.firestore.collection('messages').doc(this.message_id);

this.messageRef.collection("comments").add({ ...

Whereas it needed to be

const firebase = require("nativescript-plugin-firebase/app");

this.messageRef = firebase.firestore().collection('messages').doc(this.message_id);

Then I was able to chain a collection onto it.

THANK YOU.

Awesome, glad you got it working!

So this plugin started out with a proprietary API that I came up with to unify the iOS and Android SDK implementations. Later, I realized there's also a Web API. To support code sharing between web and native (or easy migration from web to native) I decided to add a new API that has the same interface as the Firebase Web SDK. I didn't want to remove/deprecate the old API because it would harm existing users, so that's why the Web API needs a different import.

Was this page helpful?
0 / 5 - 0 ratings