如何解决代替为所有用户运行快照,您如何设置多个查询以限制发送到设备的用户数量?
我所拥有的:所有用户的快照,带有一堆if语句,这些语句最终返回显示的用户数组。
我需要什么:快照前一行中的.query中使用的最终用户数组。
为什么我需要这样做:这一行是为了使整个用户数据库不在客户端上运行。
更具体地说,我需要查询什么: A )具有带有今天的时间戳的儿童“标题”(时间戳)且为 B )距当前用户3000英里。
数据库的JSON
"people" : {
"02PdiNpmW3MMyJt3qPuRyTpHLaw2" : {
"Coordinates" : {
"latitude" : -25.809620667034363,"longitude" : 28.321706241781342
},"PhotoPosts" : "https://firebasestorage.googleapis.com/v0/b/daylike-2f938.appspot.com/o/images%2F02PdiNpmW3MMyJt3qPuRyTpHLaw2%2FPhotoPosts?alt=media&token=24fee778-bcda-44e3-aa26-d7c2f8509740","caption" : 1602596281762,/// this is timestamp
"postID" : "02PdiNpmW3MMyJt3qPuRyTpHLaw2"
},"e1" : “cvvvv666","e2" : "aol.com"," "postID" : "0RnqWV7Gd9Z0bUW9nUvizMQOjK73","users" : "cvvvv666@aol.com"
},
。
var dict = CLLocation()
...
dict = CLLocation(latitude: lat,longitude: lon)
...
let thisUsersUid = Auth.auth().currentUser?.uid
//this line below is where the refArtists2 query should go. in other words send all users to device that meet the 2 if statements,which is represented by self.people.append(peopl)//
let refArtists2 = Database.database().reference().child("people").queryOrdered(byChild: "caption").queryEqual(toValue: ANY Timestamp in today).queryOrdered(byChild:Coordinates). queryEqual(toValue:ThoseCoordinates which make the distance to current user less than 3000 miles)
refArtists2.observe(DataEventType.value,with: { snapshot in
if snapshot.childrenCount>0{
self.people.removeAll()
for people in snapshot.children.allObjects as! [DataSnapshot] {
if people.key != thisUsersUid {
let peopleObject = people.value as? [String: AnyObject]
let peopleCoordinates = peopleObject?["Coordinates"] as? String
let peoplecaption = peopleObject?["caption"] as? Int //is timestamp
let peoplepostID = peopleObject?["postID"] as? String
let coordSnap = people.childSnapshot(forPath: "Coordinates")
guard let lat = coordSnap.childSnapshot(forPath: "latitude").value as? CLLocationDegrees else { return }
guard let lon = coordSnap.childSnapshot(forPath: "longitude").value as? CLLocationDegrees else { return }
let locCoord = CLLocation(latitude: lat,longitude: lon)
let coordSnap12 = people.childSnapshot(forPath: "caption").value as? Int ?? 0
let date = Date(timeIntervalSince1970: TimeInterval(coordSnap12)/1000.0)
//let secondsInDay = 86400
**if Calendar.current.isDateInToday(date)** {
let distance = locCoord.distance(from: self.dict)
print(distance,"distancexy")
**if distance/1609.344 < 3000**{
let peopl = Userx(Coordinates: peopleCoordinates,distance:distance,caption: peoplecaption,postID: peoplepostID)
self.people.append(peopl)
let d = people.key as! String
self.printPersonInfo(uid:d) ///////This is used to reload the data
} else {
print ("w")
}
} else {
print ("alphaaa")
}
}
print("aaaaaaaa",self.people.map {$0.distance})
}
self.people.sort { ($0.distance ?? 0) < ($1.distance ?? 0) } ////////This sorting with distance is used with returning the cell. people is used as uid array to return the cell.
}
})
} else {
print("no")
}
})
辅助警告:self.people.sort { ($0.distance ?? 0) < ($1.distance ?? 0) }
排序很重要,因此查询不应阻止这种情况。我对使用queryOrdered有点担心,因为它以错误的顺序对用户数组进行排序。如果是,则 C )查询应为:用户的顺序必须是最接近已登录用户的用户。离登录用户最远的位置必须位于数组的最后。
另一种询问方式是:创建快照时,如何查询快照的“最终结果排序”而不是运行所有用户的快照?
时间戳是自1970年以来的秒数
我尝试下面的日期查询。我获取了代码,并尝试将获取日期的代码放在实际查询之前(当前获取日期的代码位于所有用户的快照之后)。
var ppp: String! ////this should be the uid of all users in db
let people = Database.database().reference().child("people").child(self.ppp).child("captions")
people.observe(DataEventType.value,with: { snapshot in
let captionss = snapshot.value as? Int ?? 0
let date = Date(timeIntervalSince1970: TimeInterval(captionss)/1000.0)
let query1 = Database.database().reference().child("people").queryOrdered(byChild: "caption").where?(isDateInToday(date))
解决方法
编辑:此答案在Firestore中,而不是在实时数据库中。但是,概念是相同的。
问题是多个问题合而为一;询问距离,复合查询以及一般如何查询Firebase。我将发布此答案以解决后两个问题,并在问题的注释中解决距离查询。
一旦了解了查询模式,它们就会变得更容易且最重要;显而易见,数据的结构取决于要对数据运行的查询。
假设我们有一个包含用户文档的users集合-每个documentId是用户uid
users
uid_0
name: "Leroy"
,然后我们为用户提供了帖子-每个帖子都包含一些文本,该帖子的时间戳,发布该帖子的用户的uid,主题是什么以及该帖子中出现的图片的网址。注意,我将帖子存储在单独的集合中;当我们只想知道他们的帖子时,为什么要读一堆用户数据。
posts
post_id
postText: "pretty flowers"
postDate: "20201103"
postUrl: "www....."
postUid: "uid_0"
postTopic: "flowers"
假设我们要从今天开始获取关于鲜花的帖子,然后再获取发布者的姓名和输出,以及发布消息的人和他们所说的话。
为此,我们将需要一个复合查询,然后一个子查询来检索海报名称。
func getTodaysPostsAboutFlowers() {
let postsCollection = self.db.collection("posts")
let query = postsCollection.whereField("postDate",isEqualTo: "20201103").whereField("postTopic",isEqualTo: "flowers")
query.getDocuments(completion: { snapshot,error in
if let err = error {
print(err.localizedDescription)
return
}
guard let docs = snapshot?.documents else { return }
for doc in docs {
let postText = doc.get("postText") as? String ?? "No text"
guard let postersUid = doc.get("postUid") as? String else { return }
self.outputPostTextAndUserName(withText: postText,andUid: postersUid)
}
})
}
上面对postDate字段和postTopic字段执行复合查询。
上面的代码然后调用另一个函数来检索用户名,并输出用户名和他们所说的话
func outputPostTextAndUserName(withText: String,andUid: String) {
let usersCollection = self.db.collection("users")
let theUserDoc = usersCollection.document(andUid)
theUserDoc.getDocument(completion: { documentSnapshot,error in
if let err = error {
print(err.localizedDescription)
return
}
if let doc = documentSnapshot {
let postersName = doc.get("name") as? String ?? "No Name"
print("\(postersName) posted: \(withText)")
}
})
}
和输出
Leroy posted: pretty flowers
如您所见,无需加载所有用户,也无需迭代结果等。即使您有十亿用户,也只会返回该数据的一部分,这是工作时的最佳实践具有庞大的数据集;仅获取您感兴趣的数据。
修改。 OP正在询问有关包含今天的节点的查询。一种简单的解决方案是让一个子节点包含一个时间戳,该时间戳将包含特定的日期数据,然后让另一个子节点仅包含YYYYMMDD格式的当日数据。
人 uid_x 时间戳:9023490823498 //日期(timeIntervalSince1970: todaystamp:“ 20201106” // yyyymmdd格式
这使得查询包含今天的节点非常简单。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。