swift - Firestore - 创建集合的副本
问题描述
所以我有一个名为“草稿”的集合,其中包含多个文档,每个文档都有一个自动 ID。每个文档都包含字段“名称”和“详细信息”。每个文档都显示在“nameLabel”和“detailsLabel”下的 tableViewCell 中。我想做的是,当用户单击第一个 viewController 屏幕顶部的按钮时,将创建集合“草稿”的副本并将其粘贴在名为“消息”的新集合名称下。然后,该集合引用第二个 viewControllers tableViewCells,就像在第一个 ViewController 上一样,只是这次它在集合“消息”下被引用。做了一些研究后,我有一个模糊的倾向,即答案使用云函数来创建集合的副本并将其粘贴到新的集合名称中。但是对于编码和firebase来说相对较新,我不知道如何做到这一点,也不知道这是否是正确的解决方案。请有人帮忙,非常感谢任何帮助!谢谢!
第一个视图控制器
func loadDrafts() {
let userRef = db.collection("Users").document(user!)
let draftsRef = userRef.collection("Drafts")
exercisesRef.getDocuments { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
if let snapshot = querySnapshot {
for document in snapshot.documents {
let data = document.data()
let name = data["name"] as? String ?? ""
let details = data["details"] as? String ?? ""
let newDrafts = DraftMessages(name: name, details: details)
self.array.append(newDrafts)
}
self.tableView.reloadData()
}
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! DraftsCell
cell.nameLabel.text = array[indexPath.row].name
cell.detailsLabel.text = array[indexPath.row].details
return cell
}
@IBAction func goButton(_ sender: UIButton) {
\\ Add code here to create copy of previous collection "Drafts" and paste in new collection "Messages"
}
第二个视图控制器
func loadData() {
let userRef = db.collection("Users").document(user!)
userRef.collection("Messages").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let data = document.data()
let name = data["name"] as? String ?? ""
let details = data["details"] as? String ?? ""
let newMessages = Messages(name: name, details: details)
self.array.append(newMessages)
}
self.tableView.reloadData()
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MessagesCell
cell.nameLabel.text = array[indexPath.row].name
cell.detailsLabel.text = array[indexPath.row].details
return cell
}
解决方案
这是我的工作解决方案。非常感谢弗兰克斯的帮助!
@IBAction func goButton(_ sender: UIButton) {
let userRef = db.collection("Users").document(user!)
let draftsRef = userRef.collection("Drafts")
draftsRef.getDocuments { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
if let snapshot = querySnapshot {
for document in snapshot.documents {
let data = document.data()
let batch = self.db.batch()
let docset = querySnapshot
let messagesRef = userRef.collection("Messages").document()
docset?.documents.forEach {_ in batch.setData(data, forDocument: messagesRef)}
batch.commit(completion: { (error) in
if let error = error {
print("\(error)")
} else {
print("success")
}
})
}
}
}
}
}
编辑 Vaibhav Jhaveri:
这个函数(希望)同时复制获取的文档数据和该文档子集合中的数据。(虽然我没有测试过这个)
func duplicate() {
let userRef = db.collection("Users").document(userID)
let batch = self.db.batch()
let draftsRef = userRef.collection("Drafts")
draftsRef.getDocuments { (snapshot, err) in
if let err = err {
print(err.localizedDescription)
return
}
guard let snapshot = snapshot else { return }
snapshot.documents.forEach({ (document) in
let data = document.data()
let messageID = UUID().uuidString
let messagesRef = userRef.collection("Messages").document(messageID)
batch.setData(data, forDocument: messagesRef, merge: true)
let yourSubCollectionRef = draftsRef.document(document.documentID).collection("yourSubCollection")
yourSubCollectionRef.getDocuments(completion: { (subSnapshot, subErr) in
if let subErr = subErr {
print(subErr.localizedDescription)
return
}
guard let subSnapshot = subSnapshot else { return }
subSnapshot.documents.forEach({ (subDocument) in
let subData = subDocument.data()
let subDocID = UUID().uuidString
let yourNewSubCollectionRef = userRef.collection("Messages").document(messageID).collection("yourSubCollection").document(subDocID)
batch.setData(subData, forDocument: yourNewSubCollectionRef, merge: true)
})
})
})
batch.commit()
}
}