Firestore抛出FIRInvalidArgumentException:文档路径不能为空,相同代码在其他项目可正常运行
嘿,我来帮你定位这个问题。从你贴的代码、崩溃日志来看,虽然这段代码在另一个项目能正常工作,但当前项目的崩溃原因非常明确——你传给Firestore的文档ID(也就是deviceId)是空的或者不符合Firestore的文档ID规则。
先看崩溃栈里的关键调用链:
Fatal Exception: FIRInvalidArgumentException ... 5 Rayo 0x2b8e90 -[FIRCollectionReference documentWithPath:] 6 Rayo 0x24dd8 specialized LogicView.checkIfBlacklisted() + 56 (LogicView.swift:56)
这说明崩溃直接发生在db.collection("blacklist").document(deviceId)这一步,Firestore的document(_:)方法接收到了无效的路径参数,所以抛出了FIRInvalidArgumentException。
问题出在deviceId的校验逻辑
你的代码里用了guard let deviceId = UserDefaults.standard.string(forKey: "deviceID") else { ... },但这个判断只会过滤nil值,不会过滤空字符串""!如果当前项目中UserDefaults的"deviceID"对应的是空字符串,这个guard会顺利通过,但Firestore严格禁止使用空字符串作为文档ID——这就是崩溃的根源。而另一个项目里的deviceID是有效的非空字符串,所以没有触发这个问题。
具体修复方案
加强
deviceId的合法性校验
修改checkIfBlacklisted函数里的guard语句,不仅要判断是否存在,还要确保它非空且符合Firestore的文档ID规则:func checkIfBlacklisted() { // 先调试打印,看看当前deviceID的实际值 let rawDeviceId = UserDefaults.standard.string(forKey: "deviceID") print("当前deviceID的值:\(rawDeviceId ?? "nil")") guard let deviceId = rawDeviceId, !deviceId.isEmpty, !deviceId.contains("/"), deviceId != ".", deviceId != ".." else { print("Device ID无效:要么为空,要么包含Firestore不允许的字符") return } let db = Firestore.firestore() let blacklistRef = db.collection("blacklist").document(deviceId) // 后续代码保持不变... }排查
deviceID的生成逻辑
你需要检查当前项目中,是如何生成并存储deviceID到UserDefaults的:- 是不是获取设备唯一标识的代码在当前项目中没有正确执行(比如缺少权限配置,或者调用时机不对)?
- 是不是生成逻辑存在bug,导致返回了空字符串?
补充:Firestore文档ID的核心规则
避免后续再踩类似的坑,记住Firestore对文档ID的要求:
- 不能是空字符串
- 不能包含
/字符(这是集合路径的分隔符) - 不能是
.或..(路径遍历的特殊符号) - 长度不能超过1500字节
- 不能包含ASCII控制字符(0x00到0x1F、0x7F)
备注:内容来源于stack exchange,提问作者Nat Serrano

