firebase查询返回错误的快照

时间:2018-06-18 07:08:52

标签: ios swift firebase firebase-realtime-database

所以我有一个使用firebase的应用程序。在这个应用程序中,我想抓取结束时间大于或等于当天的事件。我做了这个功能,我相信完成了。但是,它什么都不返回

static func show(forEventKey eventKey: String, completion: @escaping (Event?) -> Void) {
    print(eventKey)
    let ref = Database.database().reference().child("events").child(eventKey)

    ref.queryOrdered(byChild: "end")
        .queryStarting(atValue: Date().timeIntervalSince1970, childKey: "end")
        .observeSingleEvent(of: .value, with: { (snapshot) in

            print(snapshot)

            guard let event = Event(snapshot: snapshot) else {
                return completion(nil)
            }

            completion(event)

        })
}

事件节点下我树中的一个孩子看起来像这样

"BEVT" : {
  "attend:count" : 5,
  "event:category" : "Seize The Night",
  "event:city" : "Philadelphia",
  "event:date" : {
    "end:date" : "06/18/2018",
    "end:time" : "7:01 PM",
    "start:date" : "06/17/2018",
    "start:time" : "12:01 PM"
  },
  "event:datetime" : {
    "end" : 1529362860,
    "start" : 1529251260
  },
  "event:description" : "Travis Scott is ready to hit the road. The 24-year-old hitmaker will embark on his Birds Eye View tour, powered by Live Nation, in support of his sophomore album and Billboard 200 No. 1 Birds in the Trap Sing McKnight.",
  "event:imageURL" : "https://firebasestorage.googleapis.com/v0/b/eventful-3d558.appspot.com/o/event_flyers%2FtravisScott-compressor.png?alt=media&token=c6e46da1-1395-4a37-a8fc-3ff53d5c0d4d",
  "event:name" : "birds eye view tour",
  "event:promo" : "https://firebasestorage.googleapis.com/v0/b/eventful-3d558.appspot.com/o/event_promo_vid%2FBEVT%2FTravis%20Scott_%20Houston%20Birds%20Eye%20View%20Tour%20Promo.mp4?alt=media&token=6d27d76e-281e-4083-a0ff-dbe2f25703e7",
  "event:state" : "PA",
  "event:street:address" : "5748 Baltimore Pike",
  "event:zip" : 19143
}

当我打印快照时,它看起来像是显示它找到它但它不会返回整个快照

Snap (BEVT) {
    "event:datetime" =     {
        end = 1529445600;
        start = 1529442000;
    };
}

任何人都可以看到我的查询出错了,因为我有点困惑吗?

我正在使用geofire获取密钥,因为我的应用程序是基于位置的。抓住这些钥匙后,我会提取相关信息。我很肯定我无法改变geofire存储的方式。因此,我只需要抓住密钥并返回快照并根据当前日期创建事件对象。所以基本上如果事件结束日期晚于今天则返回它。如果不是

我有这个eventsbylocation节点,它使用geofire根据位置抓取密钥。假设我在BEVT附近,这是一个事件关键,geoFire会抓住那把钥匙。现在,事件位置节点不包含日期。通过geofire获取密钥后,我仅根据从geofire收到的密钥查询事件节点。我如何根据这个密钥集合进行查询,并且仅在基于该时间标准的特定日期之后返回那些密钥。

"eventsbylocation" : {
    "ABP" : {
      ".priority" : "dr4e3nzh0q",
      "g" : "dr4e3nzh0q",
      "l" : [ 39.9840919, -75.1808035 ]
    },
    "BEVT" : {
      ".priority" : "dr4e0r56u7",
      "g" : "dr4e0r56u7",
      "l" : [ 39.9412882, -75.21873459999999 ]
    }

这是通过geoFire

抓取密钥的功能
 static func showEvent(for currentLocation: CLLocation,completion: @escaping ([Event]) -> Void) {
        //getting firebase root directory
        var keys = [String]()
        var currentEvents = [Event]()
        var geoFireRef: DatabaseReference?
        var geoFire:GeoFire?
        geoFireRef = Database.database().reference().child("eventsbylocation")
        geoFire = GeoFire(firebaseRef: geoFireRef!)
        let circleQuery = geoFire?.query(at: currentLocation, withRadius: 17.0)
        circleQuery?.observe(.keyEntered, with: { (key: String!, location: CLLocation!) in
            print("Key '\(key)' entered the search area and is at location '\(location)'")
            if let currentKey = key {
                keys.append(currentKey)
            }
        })

        circleQuery?.observeReady({
            let dispatchGroup = DispatchGroup()
            for key in keys {
                dispatchGroup.enter()
                EventService.show(forEventKey: key, completion: { (event) in
                    if let currentEvent = event {
                        currentEvents.append(currentEvent)
                    }
                    dispatchGroup.leave()
                })
            }

            dispatchGroup.notify(queue: .main, execute: {
                print(currentEvents.count)
                completion(currentEvents)
            })

        })

    }

2 个答案:

答案 0 :(得分:0)

您的代码试图过于具体,而且您要告诉它查看查询中数据的特定结尾 - 这没有意义,就好像您知道确切的路径一样,您不会这样做。需要查询!

这是一个常见的误解 - 只需记住,查询需要提供父节点,然后是你要查询的子节点,因为它将遍历父节点下面的child_nodes。

parent_node
  child_node
     child_node_of_what_you_are_querying
  child_node
     child_node_of_what_you_are_querying

所以你的查询应该是这样的。

 let ref = Database.database().reference().child("events").child("event_Key")

 ref.queryOrdered(byChild: "end")
    .queryStarting(atValue: Date().timeIntervalSince1970)
    .observeSingleEvent(of: .value, with: { (snapshot) in

     print(snapshot)

    })

答案 1 :(得分:0)

我们无法确定足够的事件节点,但我们假设一个非常简单的事件结构可能与您的事件相匹配。如果没有,请告诉我,我会更新。

events
   event_0 // BEVT in your structure?
      attend_count: 3
      event_datetime
         end: 5
         start: 3
   event_1
      attend_count: 7
      event_datetime
         end: 6
         start: 2
   event_2
      attend_count: 9
      event_datetime
         end: 5
         start: 1

我们将利用Firebase深层查询或深层路径查询来检索您想要的节点。

假设我们想要所有以5结尾的事件,这里的代码可以深入挖掘并检索event_0和event_2

let eventsRef = self.ref.child("events")
let eventQuery = eventsRef.queryOrdered(byChild: "event_datetime/end").queryEqual(toValue: 5)
eventQuery.observeSingleEvent(of: .value, with: { snapshot in
    for child in snapshot.children {
        let snap = child as! DataSnapshot
        let dict = snap.value as! [String: Any]
        let attendCount = dict["attend_count"] as! Int
        let eventDateTimeSnap = snap.childSnapshot(forPath: "event_datetime")
        let eventDateTimeDict = eventDateTimeSnap.value as! [String: Any]
        let end = eventDateTimeDict["end"] as! Int
        let start = eventDateTimeDict["start"] as! Int
        print("event: \(snap.key)  attending: \(attendCount)  start: \(start)  end:\(end)")
    }
})

和输出

event: event_0 attending: 3  start: 3  end:5
event: event_2 attending: 9  start: 1  end:5

通过这个例子,我们得到的事件以5结尾。您可以轻松扩展查询以获取在1到5之间结束的事件或今天之后的事件(通过时间戳如20180619)等。