0
votes

I have a method that returns a string that I know for sure points to a document. When using that string as follow:

const docRef = "users/uid/data/online"
const dbPath = db.doc(docRef)
console.log(dbPath.path)
return dbPath.set({"test" : 1})

It fails:

enter image description here

If I use db.collection("users").doc(uid)...... it works. How can I create a document reference through a string in typescript?

It should work according to the docs: https://firebase.google.com/docs/firestore/data-model#references

edit: This is my class:

export enum UserCollection {
    online = "online",
    private = "private",
    server = "server"
}

export enum UserDocument { 
    online = "online",
    private = "private",
    server = "server"
}

class ManagerPath { 

    pathToUser = "users/"

    getPathToUser(uid: string, userCollection: UserCollection, userDocument: UserDocument): string { 
        return this.pathToUser + "/" + uid + "/" + userCollection + "/" + userDocument;
    }

}

export const managerPath = new ManagerPath();

And this is how I retrieve a path:

exports.initializeNewUser = functions.auth.user().onCreate((user) => {
    const test = managerPath.getPathToUser(user.uid, UserCollection.online, UserDocument.online);
    console.log(test)
    const dbPath = db.doc(test)
    return dbPath.set({"dateCreation" : Date.now()}) //fails
})
1
Where are you getting the path string from? How are you creating it? Is it a field in an existing document? It would be useful to know where you are getting the variables from that are required to build the string. - Jason Berryman
@JasonBerryman I edited my question - J. Doe

1 Answers

1
votes

You may also want to create a document in the /users collection, as well as the online sub-collection. Otherwise, you'll end up with an orphaned collection. I've added some code to do this as a batch.

There are many other details that you can get from the user event, which you could save in the document, such as email, name, photoURL, etc.

I'm not sure if this is what you're looking for, but it should do what you need.

exports.initializeNewUser = functions.auth.user().onCreate((user) => {
    const userRef = db.doc(`users/${user.uid}`);
    const userOnlineRef = db.doc(`users/${user.uid}/online/online`);
    const dateCreation = user.metadata.creationTime;

    let batch = db.batch();
    batch.create(userRef, {dateCreation})
    batch.create(userOnlineRef, {dateCreation})
    return batch.commit();
})

Requires >= 1.0.0 of the Functions SDK

Fixing your code

You have declared your pathToUser as "users/" then added another /. You can fix this by modifying the following line

return this.pathToUser + "/" + uid + "/" + userCollection + "/" + userDocument;

to

return this.pathToUser + uid + "/" + userCollection + "/" + userDocument;

or

pathToUser = 'users'; // The trailing / has been removed

return `${this.pathToUser}/${uid}/${userCollection}/${userDocument}`;