如何将上传的图片关联到指定的Firebase DocumentID?
解决Firebase图片链接关联到对应Firestore文档的问题
要实现将Storage中的图片链接保存到对应的Firestore文档,你需要修正实例引用错误并调整流程顺序,确保图片上传完成后再同步文档数据,具体步骤如下:
1. 修正视图中的ViewModel实例引用
你在AddItemView的Storage代码段中重新初始化了NewItemView实例,这会导致操作的不是同一个singleitem对象,直接造成图片链接无法关联到目标文档。需要移除重复的ViewModel初始化,使用页面共享的同一个实例:
// AddItemView中只保留一个ViewModel实例 @ObservedObject var viewModel = NewItemView() // 移除Storage代码段中重复的@ObservedObject var viewModel = NewItemView()
2. 调整操作流程:先传图再同步文档
将上传图片和更新文档的顺序调整为先上传图片获取下载链接,再将链接赋值给singleitem.pic,最后添加/更新Firestore文档,确保文档创建时就包含正确的图片链接:
修改handleDoneTapped和uploadImage函数
func handleDoneTapped() { // 先执行图片上传,完成后再处理文档逻辑 uploadImage { [weak self] imageUrl in guard let self = self, let imageUrl = imageUrl else { return } // 将图片链接赋值给ViewModel中的singleitem self.viewModel.singleitem.pic = imageUrl // 调用ViewModel的方法完成文档添加/更新 self.viewModel.handleDoneTapped() self.dismiss() } } // 为uploadImage添加回调,返回图片下载链接 func uploadImage(completion: @escaping (String?) -> Void) { guard !pickedImages.isEmpty else { completion(nil) return } let storage = Storage.storage().reference() // 安全获取图片数据,避免强制解包崩溃 guard let picData = pickedImages[0].jpegData(compressionQuality: 0.5) else { completion(nil) return } let path = "itemImages/\(UUID().uuidString).jpg" let ref = storage.child(path) let metadata = StorageMetadata() metadata.contentType = "image/jpg" ref.putData(picData, metadata: metadata) { storageMetaData, error in if let error = error { print(error.localizedDescription) completion(nil) return } // 上传完成后获取图片的下载URL ref.downloadURL { url, error in if let error = error { print(error.localizedDescription) completion(nil) return } // 将URL转为字符串返回 completion(url?.absoluteString) } } }
3. 修正SingleItem的CodingKeys错误
你的CodingKeys中将description映射为空字符串键,这会导致Firestore中无法正确存储描述字段,需要修正为与属性名一致的键:
enum CodingKeys: String, CodingKey { case id case title case author case description // 移除= "" case pic }
4. 可选:同步新增文档的ID到本地(如果需要后续编辑)
在NewItemView的addItem函数中,添加文档后可以将生成的DocumentID赋值回本地的singleitem,方便后续编辑操作:
private func addItem(_ singleitem: SingleItem) { do { var addedItem = singleitem addedItem.userId = Auth.auth().currentUser?.uid // 添加文档并获取引用 let docRef = try db.collection("items").addDocument(from: addedItem) // 将生成的文档ID同步到本地singleitem self.singleitem.id = docRef.documentID } catch { print(error) } }
为什么之前的尝试失败?
- 实例不共享:你在Storage代码中重新创建了
NewItemView实例,导致修改的pic字段属于另一个独立对象,无法关联到目标文档。 - 流程顺序错误:先创建文档再上传图片,此时新文档的ID未同步到本地,无法在上传完成后更新对应文档的
pic字段,导致图片链接无法写入目标文档。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

