Swift - Firebase - 订单收集
Posted
技术标签:
【中文标题】Swift - Firebase - 订单收集【英文标题】:Swift - Firebase - order collection 【发布时间】:2020-01-01 22:11:39 【问题描述】:我正在尝试检索一些文档,但我需要按“愿望清单”中的某些数据(“ListIDX”)对它们进行排序 - collection
。
我试过了,但这是不允许的:
db.collection("users").document(userID).collection("wishlists").order(by: "ListIDX").document(list.name).collection("wünsche").getDocuments()
这是我的function
:
func getWishes ()
let db = Firestore.firestore()
let userID = Auth.auth().currentUser!.uid
var counter = 0
for list in self.dataSourceArray
print(list.name) // -> right order
db.collection("users").document(userID).collection("wishlists").document(list.name).collection("wünsche").getDocuments() ( querySnapshot, error) in
print(list.name) // wrong order
if let error = error
print(error.localizedDescription)
else
// DMAG - create a new Wish array
var wList: [Wish] = [Wish]()
for document in querySnapshot!.documents
let documentData = document.data()
let wishName = documentData["name"]
wList.append(Wish(withWishName: wishName as! String, checked: false))
// DMAG - set the array of wishes to the userWishListData
self.dataSourceArray[counter].wishData = wList
counter += 1
这是我最终真正想要实现的目标:
self.dataSourceArray[ListIDX].wishData = wList
更新
我还有一个函数可以按正确的顺序检索我的wishlists
。也许我可以在那里添加getWishes
,这样它的顺序也是正确的。
func retrieveUserDataFromDB() -> Void
let db = Firestore.firestore()
let userID = Auth.auth().currentUser!.uid
db.collection("users").document(userID).collection("wishlists").order(by: "listIDX").getDocuments() ( querySnapshot, error) in
if let error = error
print(error.localizedDescription)
else
// get all documents from "wishlists"-collection and save attributes
for document in querySnapshot!.documents
let documentData = document.data()
let listName = documentData["name"]
let listImageIDX = documentData["imageIDX"]
// if-case for Main Wishlist
if listImageIDX as? Int == nil
self.dataSourceArray.append(Wishlist(name: listName as! String, image: UIImage(named: "iconRoundedImage")!, wishData: [Wish]()))
// set the drop down menu's options
self.dropDownButton.dropView.dropDownOptions.append(listName as! String)
self.dropDownButton.dropView.dropDownListImages.append(UIImage(named: "iconRoundedImage")!)
else
self.dataSourceArray.append(Wishlist(name: listName as! String, image: self.images[listImageIDX as! Int], wishData: [Wish]()))
self.dropDownButton.dropView.dropDownOptions.append(listName as! String)
self.dropDownButton.dropView.dropDownListImages.append(self.images[listImageIDX as! Int])
// // create an empty wishlist
// wList = [Wish]()
// self.userWishListData.append(wList)
// reload collectionView and tableView
self.theCollectionView.reloadData()
self.dropDownButton.dropView.tableView.reloadData()
self.getWishes()
为了更好地理解:
git repo
【问题讨论】:
查看您建议的代码:collection("wishlists").order(by: "ListIDX").document(list.name) - 您的“wishlists”集合中可能有多个文档,但是您只获取具有 id = list.name 的一个。所以订购这些文件没有任何意义。这就是它不被支持的原因。您可能应该更好地解释您的数据结构是什么以及您想要实现什么。 @alrgrid 我需要在 sourceDataArray 的正确索引处插入 wList。那是我的问题。如果 list.name 已排序,则检索 wünsche 将是正确的顺序。你知道我的意思吗? 请不要重复问同一个问题。它将信息分布在多个帖子中。一次只关注一个问题,帮助我们帮助您。另外两个问题的cmets中提到,Firestore是异步的,数据可能在不同的时间从不同的节点返回。唯一的保证是数据是否在查询中排序 - 例如,您的listIDX
数据将按此排序。解决方案是在检索到所有数据后,通过您想要的任何属性简单地对 self.dataSourceArray
进行排序。
另一个选项,如果你想向 dataSource 数组添加额外的信息是在该数组中查找列表对象的索引,然后添加额外的数据。类似这个伪代码let index = self.dataSourceArray.firstIndex(of: list)
,然后使用该索引来更新该索引处的对象。
【参考方案1】:
正如@algrid 所说,如果您要在最后使用list.name
而不是第一个或最后一个来获取特定元素,那么使用order()
订购collection
是没有意义的。我建议将您的代码更改为:
db.collection("users").document(userID).collection("wishlists").document(list.name).collection("wünsche").getDocuments()
【讨论】:
我需要在sourceDataArray
的正确索引处插入wList
。那是我的问题。如果订购了list.name
,则检索wünsche
将是正确的顺序。你知道我的意思吗?【参考方案2】:
我正在尝试检索一些文档,但我需要它们按某些数据排序(“ListIDX”)
以下代码行肯定会帮助您实现这一目标:
db.collection("users").document(userID).collection("wishlists").order(by: "ListIDX").getDocuments() /* ... */
不允许在 .order(by: "ListIDX")
之后添加另一个 .document(list.name)
调用,因为此函数返回一个 Firestore Query
对象,并且您无法链接此类函数,因为它在该类中不存在。
此外,Firestore 查询很浅,这意味着它们只能从运行查询的集合中获取项目。无法在单个查询中从***集合和子集合中获取文档。 Firestore 不支持一次性跨不同集合进行查询。单个查询只能使用单个集合中文档的属性。所以我能想到的最简单的解决方案是使用两个不同的查询并在客户端合并结果。第一个是上面的查询,它返回一个“愿望清单”列表,第二个是一个查询,它可以帮助您获取 wünsche
子集合中每个 wishlist
对象中存在的所有愿望。
【讨论】:
我正在考虑这个问题,但我真的不知道该怎么做,因为我对 Firestore 还是很陌生。你能详细说明一下吗? :) 我还有一个function
,在那里我检索了我的wishlists
,将更新我的问题
要实现这一点,您需要使用嵌套查询。因此,将帮助您获得每个 wishlist
中存在的所有愿望的第二个查询应该放在第一个回调中,就是这样。
我看到了您编辑的问题。解决方案在我上面的评论中。你试过了吗?
我确实尝试了一些东西,但没有任何效果。我刚刚意识到这可能是其他原因毕竟因为我的dataSourceArray
是有序的,而我的for-loop
通过了有序列表,所以它应该是正确的,但它不是,我不知道为什么......我会更新我的再次用我的 git 提问。
在我在我的问题中发布的第二个函数中检索wishlists
后,dataSourceArray
的排序很好。但是我刚刚在我的getWishes
函数中打印了dataSourceArray
,并且它的顺序不再正确......【参考方案3】:
我解决了这个问题。我在保存 wish
时添加了另一个属性,该属性跟踪它被添加到的列表的索引。也许不是最顺畅的方式,但它确实有效。感谢所有帮助:)
【讨论】:
以上是关于Swift - Firebase - 订单收集的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Swift 在 Firebase 中使用相同的关键字存储不同数据的多个实例?
无法在 razorpay [firebase_functions/internal] 内部的 firebase 云函数中创建订单 ID