如何查询firebase以过滤某个值

时间:2018-01-18 23:51:07

标签: swift firebase firebase-realtime-database

我试图获取针对特定用户(UserId)的所有活动的所有imageURL。快照的内容包括正确的条目,但imageURL不会附加到imageArray。我做错了什么?

 // Get all images for a specific user

    func getImagesForUser(userId:String, handler: @escaping (_ imageArray: [String]) -> ()) {
        var imageArray = [String]()

        REF_ACTIVITY.queryOrdered(byChild: "userId").queryEqual(toValue: userId).observe(.value, with:  { snapshot in
            dump(snapshot)
            guard let data = snapshot.value as? NSDictionary else { print("else was returned"); return }

            let imageURL = data["imageURL"] as? String ?? ""
            imageArray.append(imageURL)
            handler(imageArray)
        })

    }

转储输出(快照)

Snap (-L2RDXTKANzD8YGpPl92) {
    gearId = asfasfsf;
    imageCount = 3;
    imageURLs =     {
        1 = "http://www.foo.com";
        2 = "http://www.foo2.com";
        3 = "http://www.foo3.com";
    };
    killCount = 10;
    kills = 12;
    likeCount = 2;
    likes =     {
        fas86q39rasf = 1;
    };
    userId = NhZZGwJQCGe2OGaNTwGvpPuQKNA2;
}

Snap (-L2RDXTKANzD8YGpPl92) {
    gearId = asfasfsf;
    imageCount = 3;
    imageURLs =     {
        1 = "http://www.foo.com";
        2 = "http://www.foo2.com";
        3 = "http://www.foo3.com";
    };
    killCount = 10;
    kills = 12;
    likeCount = 2;
    likes =     {
        fas86q39rasf = 1;
    };
    userId = NhZZGwJQCGe2OGaNTwGvpPuQKNA2;
}

更新 - Dict的输出

24 elements
  ▿ 0 : 2 elements
    - key : "commentCount"
    - value : 1
// removed some info
...
  ▿ 12 : 2 elements
    - key : "imageURLs"
    ▿ value : 4 elements
      - 0 : <null>
      - 1 : https://firebasestorage.googleapis.com/v0/b/shoota-179610.appspot.com/o/activity_image%2FCA6F4C93-8F5F-456C-9FD6-F2EACC444739?alt=media&token=522d957b-dedf-4bdc-9cbc-1de581284393
      - 2 : https://firebasestorage.googleapis.com/v0/b/shoota-179610.appspot.com/o/activity_image%2FCA6F4C93-8F5F-456C-9FD6-F2EACC444739?alt=media&token=522d957b-dedf-4bdc-9cbc-1de581284393
      - 3 : https://firebasestorage.googleapis.com/v0/b/shoota-179610.appspot.com/o/activity_image%2FCA6F4C93-8F5F-456C-9FD6-F2EACC444739?alt=media&token=522d957b-dedf-4bdc-9cbc-1de581284393
  ▿ 13 : 2 elements
    - key : "imageURL"
    - value : https://firebasestorage.googleapis.com/v0/b/shoota-179610.appspot.com/o/activity_image%2FCA6F4C93-8F5F-456C-9FD6-F2EACC444739?alt=media&token=522d957b-dedf-4bdc-9cbc-1de581284393
  ▿ 14 : 2 elements
    - key : "killCount"
    - value : 10

1 个答案:

答案 0 :(得分:1)

问题中的代码存在一些问题:

您似乎只想获取一次数据,但 observe 将保持附加状态,并且只要该节点中任何位置发生与查询匹配的更改,您就会收到通知。如果您只想要一次,请使用 observeSingleEvent 而不是

此外,您将使用该查询返回多个节点 - 这些节点需要通过循环一次处理一个节点以迭代返回的数据。

这是该技术的一个非常简化的例子。注意没有错误检查;例如,如果其中一个返回的节点不包含应该使用guard或者nil-coalescing运算符(??)处理的imageURL键,以便在该情况下分配默认值。

let activitesRef = self.ref.child("activities")
let query = activitesRef.queryOrdered(byChild: "userId").queryEqual(toValue: userId)
query.observeSingleEvent(of: .value, with: { snapshot in
    for child in snapshot.children {
        let snap = child as! DataSnapshot
        let dict = snap.value as! [String: Any]
        let url = dict["imageURL"] as? String ?? "no url"
        print(url)
    }
})

修改

此代码假定这样的结构

activities
  activity_0
     userId: "uid_0"
     imageURL: "www.someurl.com"
  activity_1
     userId: "uid_1"
     imageURL: "www.anotherurl.com"
  activity_2
     userId: "uid_0"
     imageURL: "www.coolurl.com"

在上述情况下,快照中将返回两个节点,上面的代码将遍历这些节点并打印每个节点的URL。

www.someurl.com
www.coolurl.com

另一个编辑:

根据一些后续评论,似乎每个用户都有多个网址。这是一个匹配的更新Firebase结构:

activities
  activity_0
     userId: "uid_1"
     urls
       url_0: "www.someurl.com"
       url_1: "www.anotherurl.com"
       url_2: "www.coolurl.com"
  activity_1
     userId: "uid_1"
     urls
       url_0: "www.thisurl.com"
       url_1: "www.thaturl.com"
       url_2: "www.ou812url.com"

请注意,在NoSQL数据库中应避免使用数组,因此我们使用的是url_0,url_1,但实际上应该使用childByAutoId创建这些节点键。

然后是代码来查询uid_1的所有节点并打印他们的网址

let activitesRef = self.ref.child("activities")
let query = activitesRef.queryOrdered(byChild: "userId").queryEqual(toValue: userId)
query.observeSingleEvent(of: .value, with: { snapshot in
    for child in snapshot.children {
        let snap = child as! DataSnapshot
        print(snap.key)
        let urlSnap = snap.childSnapshot(forPath: "urls")
        for url in urlSnap.children {
            let aUrlSnap = url as! DataSnapshot
            let key = aUrlSnap.key
            let val = aUrlSnap.value as! String
            print("  key: \(key)  url: \(val)")
        }
    }
})

最后输出

activity_0
  key: url_0  url: www.someurl.com
  key: url_1  url: www.anotherurl.com
  key: url_2  url: www.coolurl.com
activity_1
  key: url_0  url: www.thisurl.com
  key: url_1  url: www.thaturl.com
  key: url_2  url: www.ou812url.com