Swift中Firestore子集合exerciseSet数据获取失败求助
问题诊断与解决方案
核心问题分析
你遇到的问题是:从exerciseSet集合读取数据时,能获取到exercise字段的文档ID,但对应的Firestore文档快照不存在,导致最终无法加载任何exerciseSet数据。排除结构体字段问题后,问题集中在DocumentReference路径错误、权限限制或写入时引用错误这几个方向。
具体排查与解决步骤
1. 验证Exercise文档的实际存储路径
首先确认exerciseRef指向的路径是否真的存在对应文档:
- 在代码中添加打印,查看完整路径:
if let exerciseRef = data["exercise"] as? DocumentReference { print("Exercise 引用路径: \(exerciseRef.fullPath)") // 新增这行 dispatchGroup.enter() // ... 后续代码不变 } - 复制打印出的路径(比如
users/xxx/exercise/GOkkx6b02NXG6XFVAtAI),去Firebase控制台核对该路径下是否存在目标文档。- 如果路径错误(比如exercise文档实际在根集合
exercise下,而非用户子集合),需要修正写入exerciseSet时的引用路径,或者调整读取时的查询逻辑。
- 如果路径错误(比如exercise文档实际在根集合
2. 检查Firestore安全规则
如果路径正确但仍无法读取,大概率是权限限制导致:
- 临时测试:将Firestore安全规则改为宽松模式(仅用于测试,上线前务必改回):
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if true; } } } - 重新运行代码,如果能正常获取数据,说明是安全规则限制了读取权限。后续需要根据业务需求调整规则,比如允许用户读取自己的exercise文档,或公共exercise集合:
// 示例:允许读取根集合exercise下的所有文档 match /exercise/{exerciseId} { allow read: if true; allow write: if request.auth != null; }
3. 核对写入exerciseSet时的引用正确性
检查写入exerciseSet文档时,exercise字段的DocumentReference是否正确:
- 去Firebase控制台打开对应的
exerciseSet文档,查看exercise字段的引用值,确认其指向的文档ID和路径与实际存在的exercise文档一致。 - 如果写入时引用错误(比如文档ID拼写错误、集合名称写错),需要修正写入逻辑,确保存储的是正确的DocumentReference。
4. 优化代码容错逻辑
当前代码中如果exercise快照不存在,会直接跳过该exerciseSet的添加,导致最终列表为空。可以添加容错处理,避免有效数据丢失:
guard let exerciseSnapshot = exerciseSnapshot, exerciseSnapshot.exists else { print("Exercise snapshot does not exist. Exercise ID:", exerciseRef.documentID) // 创建默认exercise对象,保留当前exerciseSet数据 let defaultExercise = fbExercise( id: exerciseRef.documentID, name: "未找到训练项目", musclegroup: "", instructions: "" ) let exerciseSet = fbExerciseSet( id: document.documentID, reps: reps, weight: weight, time: time, dateCompleted: dateCompleted, exercise: defaultExercise ) exerciseSets.append(exerciseSet) return }
内容的提问来源于stack exchange,提问作者Rachel
相关产品推荐
相关产品推荐

