【问题标题】:Firebase & GeoFire fetch double adds new post to collection viewFirebase 和 GeoFire fetch double 将新帖子添加到集合视图
【发布时间】:2019-08-13 02:53:19
【问题描述】:

添加新帖子时在我的帖子数组中获得双帖子。导致我的收藏视图中有 2 个相同的新帖子

我正在运行 Firebase 实时数据库,并使用 geoFire 进行基于位置的查询。我正在将帖子添加到“帖子”并将位置数据添加到“post_locatons”。现在发布工作完美,完全没有问题。第一次加载应用程序时,我的集合视图数据可以完美地获取和加载。

只有当我添加新帖子然后重新获取数据并重新加载我的 collectionView 时,它才会将新帖子双重添加到我的帖子 = 帖子数组中。它只是新的/最后一个项目。因此,新帖子中的posts.count 总数不是10,而是11,最后2 个是相同的。我的收藏视图重新加载,我收到 2 个相同的新帖子。

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 上,一切运行良好,数据库也完美保存了所有内容,没有双重帖子和双重位置。只有当我发布新帖子并返回我的收藏视图时,fetchPosts 再次运行并且一切都很好,直到最后 2 个它在帖子中添加了另一个帖子,这是我的新帖子的两倍。

而且仅供参考,我的新发布功能从未触及过帖子,这一切都在我的 collectionView 控制器上完成。

我一直在试图弄清楚这个额外的帖子来自哪里,但没有骰子

已回答 我已经解决了这个问题,如果有人想做类似的事情,我会在下面发布我如何修复它作为答案

【问题讨论】:

    标签: ios swift firebase firebase-realtime-database geofire


    【解决方案1】:

    当您调用circleQuery.observe(.keyEntered 时,它会启动一个观察者。这将继续观察进入查询范围的键,直到您移除观察者。由于您从不移除观察者,因此您第二次调用 fetchPosts 时实际上是添加了第二个观察者,这意味着您的代码将为范围内的每个键调用两次。

    在您的类中定义句柄和查询,以便您可以在 fetchPosts 函数之外访问它

    var handle: DatabaseHandle!
    var circleQuery: GFCircleQuery!
    

    要删除观察者,请确保保留附加观察者时返回的句柄:

    circleQuery = geoFire.query(at: myLocation, withRadius: 10)
    
    self.handle = circleQuery?.observe(.keyEntered, with: { key, location in
    

    然后通过调用 fetchPosts 完成 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)
    })
    

    【讨论】:

    • 太好了,所以我快到了,我似乎无法让 circleQuery.removeObserverWithHandle(handle) 不会导致错误。你能在我的职能范围内解释安置吗? ,我得到'GFCircleQuery'类型的值没有成员'removeObserverWithHandle''。谢谢
    • 非常感谢,更新了代码,还必须添加一些文本以提供新代码的上下文
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多