Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何查询firebase以筛选特定值_Swift_Firebase_Firebase Realtime Database - Fatal编程技术网

Swift 如何查询firebase以筛选特定值

Swift 如何查询firebase以筛选特定值,swift,firebase,firebase-realtime-database,Swift,Firebase,Firebase Realtime Database,我正在尝试获取特定用户ID的所有活动的所有ImageURL。快照的内容包括正确的条目,但是imageURL不会附加到imageArray。我做错了什么 // Get all images for a specific user func getImagesForUser(userId:String, handler: @escaping (_ imageArray: [String]) -> ()) { var imageArray = [String]()

我正在尝试获取特定用户ID的所有活动的所有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)
        })

    }
dumpsnap的输出

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的输出


问题中的代码有几个问题:

看起来您只想获取一次数据,但observe将保持连接状态,并且当该节点中任何地方出现与查询匹配的更改时,都会通知您。如果只需要一次,请使用observeSingleEvent

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

这是一个非常简单的例子。注意:没有错误检查;例如,如果其中一个返回的节点不包含应使用保护或nil合并运算符处理的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
另一编辑:

根据一些后续评论,似乎每个用户都有多个URL。以下是更新后的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的所有节点并打印其url的代码

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

您可能应该从文档开始:因为文档中有时缺少示例,所以这也是一个很好的开始:在第二个问题中:数千没有问题,数万也通常没有问题,当您达到几十万/百万时,事情会变得更有趣。看,@FrankvanPuffelen:谢谢你的链接。它们很有用。我已经用我的新代码更新了我的问题。我还有一些问题,但我很接近,我想…谢谢你的意见。我已经玩了一段时间了,但是没有成功。它在let dict行失败。。。斯威夫特还指出,这将永远失败。。。我还没把它修好。@Chris_1983_挪威哎呀!我的代码有一个输入错误;需要snap.value,而不仅仅是snap。Snap是快照,Snap.value是我们要查找的数据。现在就试试吧,非常抱歉。我应该在发布之前测试一下。它现在已经过测试,将迭代并打印所有url,其中用户ID等于您要查找的uid。我还添加了一个nil合并操作符来保护代码,以防其中一个快照中没有imageURL节点。不用担心。是我感谢你甚至花时间来帮助我。@Chris_1983_Norway我希望答案有帮助!如果是这样,一定要接受它,这样它也能帮助别人。。我还将ImageURL更改为多个图像的dict。请参阅更新后的问题以获取dict的打印输出。我想我需要循环此问题以将其添加到本地数组中?
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