Firebase 和 GeoFire fetch double 添加了新的 post 到 collection 视图
Firebase & GeoFire fetch double adds new post to collection view
在我的 Posts 数组中添加新的 posts 时得到双 posts。在我的 collection 视图
中产生了 2 个相同的新 post
Im 运行 Firebase 实时数据库,使用 geoFire 进行基于位置的查询。我将 posts 添加到 'posts' 并将位置数据添加到 'post_locatons'。现在 posting 工作完美,完全没有问题。并首次加载该应用程序时,我的 collection 视图数据可以完美地获取和加载。
仅当我添加一个新的 post 然后重新获取数据并重新加载我的 collection 视图时,它是否将新的 post 双重添加到我的 posts = Post数组。而且它只是 new/last 项。所以 posts.count 与新 post 的总和不是 10,而是 11,最后 2 个是相同的。我的 collection 视图重新加载我得到 2 个相同的新 posts.
func refreshCollectionView() {
self.collectionView.reloadData()
}
func fetchPosts(handleComplete:@escaping (()->())) {
self.posts.removeAll()
guard let curLat = liveSavedPlace?.coordinate.latitude else { return }
guard let curLong = liveSavedPlace?.coordinate.longitude else { return }
let myLocation = CLLocation(latitude: curLat, longitude: curLong)
let ref = Database.database().reference()
let geofireRef = ref.child("posts_location")
let geoFire = GeoFire(firebaseRef: geofireRef)
let circleQuery = geoFire.query(at: myLocation, withRadius: 10)
circleQuery.observe(.keyEntered, with: { key, location in
POSTS_REF.child(key).observeSingleEvent(of: .value) { (snapshot) in
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else { return }
let post = Post(postId: key, dictionary: dictionary)
self.posts.append(post)
handleComplete()
}
})
}
就像我说的,在 viewDidLoad 上,一切都完美无缺,数据库也完美地保存了一切,没有双重 posts 也没有双重位置..只有当我 post 一个新的和回到我的 collection 视图,fetchPosts 再次运行,一切都很好,直到最后 2 个它添加另一个 Post 到 posts 那是我新的两倍post.
仅供参考,我的新 Posting 功能从未触及 posts,这一切都在我的 collectionView 控制器上完成。
我一直在试图弄清楚这个额外的 post 是从哪里来的,但是没有骰子
已回答
我解决了这个问题,如果有人想做类似的事情,我 post 在下面说明了我是如何修复它的作为答案
当您调用 circleQuery.observe(.keyEntered
时,它会启动一个观察者。这将继续观察进入查询范围的键,直到您删除观察者。由于您永远不会删除观察者,因此第二次调用 fetchPosts
实际上是在添加第二个观察者,这意味着您的代码将针对范围内的每个键调用两次。
在您的 class 中定义句柄和查询,这样您就可以在 fetchPosts 函数之外访问它
var handle: DatabaseHandle!
var circleQuery: GFCircleQuery!
要删除观察者,请确保保留附加观察者时返回的句柄:
circleQuery = geoFire.query(at: myLocation, withRadius: 10)
self.handle = circleQuery?.observe(.keyEntered, with: { key, location in
然后通过调用 fetchPosts completion Handler 移除观察者:
func refreshCollectionView() {
circleQuery?.removeObserver(withFirebaseHandle: handle)
self.collectionView.reloadData()
}
如果您在调用 fetchPosts
时只是在查询范围内寻找对象并且不想继续观察,您通常会在 GeoFire 为所有对象调用后移除观察者初始对象,即 'ready' with the query:
circleQuery.observeReadyWithBlock({
print("All initial data has been loaded and events have been fired!")
circleQuery.removeObserverWithHandle(handle)
})
在我的 Posts 数组中添加新的 posts 时得到双 posts。在我的 collection 视图
中产生了 2 个相同的新 postIm 运行 Firebase 实时数据库,使用 geoFire 进行基于位置的查询。我将 posts 添加到 'posts' 并将位置数据添加到 'post_locatons'。现在 posting 工作完美,完全没有问题。并首次加载该应用程序时,我的 collection 视图数据可以完美地获取和加载。
仅当我添加一个新的 post 然后重新获取数据并重新加载我的 collection 视图时,它是否将新的 post 双重添加到我的 posts = Post数组。而且它只是 new/last 项。所以 posts.count 与新 post 的总和不是 10,而是 11,最后 2 个是相同的。我的 collection 视图重新加载我得到 2 个相同的新 posts.
func refreshCollectionView() {
self.collectionView.reloadData()
}
func fetchPosts(handleComplete:@escaping (()->())) {
self.posts.removeAll()
guard let curLat = liveSavedPlace?.coordinate.latitude else { return }
guard let curLong = liveSavedPlace?.coordinate.longitude else { return }
let myLocation = CLLocation(latitude: curLat, longitude: curLong)
let ref = Database.database().reference()
let geofireRef = ref.child("posts_location")
let geoFire = GeoFire(firebaseRef: geofireRef)
let circleQuery = geoFire.query(at: myLocation, withRadius: 10)
circleQuery.observe(.keyEntered, with: { key, location in
POSTS_REF.child(key).observeSingleEvent(of: .value) { (snapshot) in
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else { return }
let post = Post(postId: key, dictionary: dictionary)
self.posts.append(post)
handleComplete()
}
})
}
就像我说的,在 viewDidLoad 上,一切都完美无缺,数据库也完美地保存了一切,没有双重 posts 也没有双重位置..只有当我 post 一个新的和回到我的 collection 视图,fetchPosts 再次运行,一切都很好,直到最后 2 个它添加另一个 Post 到 posts 那是我新的两倍post.
仅供参考,我的新 Posting 功能从未触及 posts,这一切都在我的 collectionView 控制器上完成。
我一直在试图弄清楚这个额外的 post 是从哪里来的,但是没有骰子
已回答 我解决了这个问题,如果有人想做类似的事情,我 post 在下面说明了我是如何修复它的作为答案
当您调用 circleQuery.observe(.keyEntered
时,它会启动一个观察者。这将继续观察进入查询范围的键,直到您删除观察者。由于您永远不会删除观察者,因此第二次调用 fetchPosts
实际上是在添加第二个观察者,这意味着您的代码将针对范围内的每个键调用两次。
在您的 class 中定义句柄和查询,这样您就可以在 fetchPosts 函数之外访问它
var handle: DatabaseHandle!
var circleQuery: GFCircleQuery!
要删除观察者,请确保保留附加观察者时返回的句柄:
circleQuery = geoFire.query(at: myLocation, withRadius: 10)
self.handle = circleQuery?.observe(.keyEntered, with: { key, location in
然后通过调用 fetchPosts completion Handler 移除观察者:
func refreshCollectionView() {
circleQuery?.removeObserver(withFirebaseHandle: handle)
self.collectionView.reloadData()
}
如果您在调用 fetchPosts
时只是在查询范围内寻找对象并且不想继续观察,您通常会在 GeoFire 为所有对象调用后移除观察者初始对象,即 'ready' with the query:
circleQuery.observeReadyWithBlock({
print("All initial data has been loaded and events have been fired!")
circleQuery.removeObserverWithHandle(handle)
})