Firestore为子集合文档设置自定义ID报错求助
问题与解决方案
问题描述
我正在为学生开发一款待办应用,学生可创建项目并添加其他学生,创建项目时会自动将当前用户加入该项目。目前我能为projects集合的项目设置自定义ID,也能为users子集合添加自动生成ID的用户,但尝试为用户设置自定义ID时触发错误:
FirebaseError: Invalid collection reference. Collection references must have an odd number of segments, but projects/secondProject/users/Stefje123 has 4.
相关代码如下:
const createProject = async (e: any) => { const newName = document.querySelector<HTMLInputElement>('#newName')?.value; const newDate = document.querySelector<HTMLInputElement>('#newDate')?.value; const newDescription = document.querySelector<HTMLInputElement>('#newDescription')?.value; const username = auth.currentUser?.displayName; e.preventDefault(); const project = await setDoc(doc(db, 'projects', newName), { Name: newName, Deadline: Timestamp.fromDate(new Date(newDate)), Description: newDescription, }); const user = await addDoc(collection(db, 'projects', newName, 'users', username), { Name: auth.currentUser!.displayName, UID: auth.currentUser!.uid, Email: auth.currentUser!.email, }); };
问题原因
你搞混了Firebase集合与文档API的使用规则:
collection()用于指向集合,路径段数必须是奇数(比如projects是1段、projects/xxx/users是3段)doc()用于指向具体文档,路径段数必须是偶数(比如projects/xxx是2段、projects/xxx/users/yyy是4段)
你当前用collection(db, 'projects', newName, 'users', username)生成的路径是4段,不符合集合的段数要求——这里的username应该是users集合下的文档ID,而非新的集合名。
修复代码
把添加用户的逻辑改成用doc()指定自定义文档ID,再用setDoc()写入数据:
const createProject = async (e: any) => { const newName = document.querySelector<HTMLInputElement>('#newName')?.value; const newDate = document.querySelector<HTMLInputElement>('#newDate')?.value; const newDescription = document.querySelector<HTMLInputElement>('#newDescription')?.value; const username = auth.currentUser?.displayName; // 先判断用户信息是否存在,避免空值报错 if (!username || !auth.currentUser) return; e.preventDefault(); await setDoc(doc(db, 'projects', newName), { Name: newName, Deadline: Timestamp.fromDate(new Date(newDate)), Description: newDescription, }); // 用doc()指向users集合下的指定用户文档,setDoc写入自定义ID的文档 await setDoc(doc(db, 'projects', newName, 'users', username), { Name: auth.currentUser.displayName, UID: auth.currentUser.uid, Email: auth.currentUser.email, }); };
额外提醒
- 建议增加用户信息的非空判断,避免未登录或信息缺失导致的错误
- 如果存在用户名重复的可能,用用户的
uid作为文档ID会更可靠,因为uid是Firebase用户的唯一标识
内容的提问来源于stack exchange,提问作者Stef Verniers
相关产品推荐
相关产品推荐

