Reputation: 65
I'm having troulbe figuring out how to add a subcollection to a document in my React App. I'm also getting the error that db.collection() is not a function. I'm trying to add the subcollection in the registerWithEmailAndPassword function. The Firebase Firestore documentation does not specify how to create a subcollection. Any help would be greatly appreciated thank you. Firebase config has been ommited to protect my API key.
import { initializeApp } from "firebase/app";
import {
GoogleAuthProvider,
getAuth,
signInWithPopup,
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
sendPasswordResetEmail,
signOut,
} from "firebase/auth";
import {
getFirestore,
query,
getDocs,
collection,
where,
addDoc,
Firestore,
doc,
DocumentReference,
setDoc
} from "firebase/firestore";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const googleProvider = new GoogleAuthProvider();
const signInWithGoogle = async () => {
try {
const res = await signInWithPopup(auth, googleProvider);
const user = res.user;
const q = query(collection(db, "users"), where("uid", "==", user.uid));
const docs = await getDocs(q);
if (docs.docs.length === 0) {
await addDoc(collection(db, "users"), {
uid: user.uid,
name: user.displayName,
authProvider: "google",
email: user.email,
});
}
} catch (err) {
console.error(err);
alert(err.message);
}
};
const logInWithEmailAndPassword = async (email, password) => {
try {
await signInWithEmailAndPassword(auth, email, password);
} catch (err) {
console.error(err);
alert(err.message);
}
};
const registerWithEmailAndPassword = async (name, email, password) => {
try {
const res = await createUserWithEmailAndPassword(auth, email, password);
const user = res.user;
const userDoc = await addDoc(collection(db, "users"), {
uid: user.uid,
name,
authProvider: "local",
email,
});
db.collection("users").doc(userDoc.id).collection("test");
} catch (err) {
console.error(err);
alert(err.message);
}
};
const sendPasswordReset = async (email) => {
try {
await sendPasswordResetEmail(auth, email);
alert("Password reset link sent!");
} catch (err) {
console.error(err);
alert(err.message);
}
};
const logout = () => {
signOut(auth);
};
export {
auth,
db,
signInWithGoogle,
logInWithEmailAndPassword,
registerWithEmailAndPassword,
sendPasswordReset,
logout,
};
Upvotes: 3
Views: 2123
Reputation: 599956
This code uses the classic, namespaced syntax of Firebase SDK version 8 and before:
db.collection("users").doc(userDoc.id).collection("test");
But the rest of your code uses the new modular syntax of Firebase SDK versions 9 and later. The equivalent there would be:
collection(doc(collection(db, "users"), userDoc.id), "test")
Or more concisely:
collection(db, "users", userDoc.id, "test")
The above creates a reference to the subcollection, but doesn't create the collection in the database yet. A collection is created once a document is written to it, and removed automatically once the last document is removed from it.
So you can create a document in test
(and thus create test
) with:
const testCollection = collection(db, "users", userDoc.id, "test");
addDoc(testCollection, { title: "hello world })
Upvotes: 4