首页 > 解决方案 > Firebase 的 ref().child(stringPath: String) 返回整个顶级集合

问题描述

我正在尝试使用 swiftUI 检索我的 Firebase 数据库的特定子项。为此,我使用简单的表达式

func addListeners() {
    let database = Database.database(url: "https://someUrl")
    let ref = database.reference(withPath: "users")
    let currentUserId = "u3Ebr6M3BAbP7PBSYYJ7q9kEe1l2"
    let drivingTowardsRef = database.reference(withPath: "users/\(currentUserId)/drivingTowardsUsers")
    print("Loading data from \(drivingTowardsRef)")
    
    //THIS RIGHT HERE IS CAUSING THE PROBLEM
    ref.observe(.childAdded) { snapshot in
        print("Got TOP LEVEL data for user \(snapshot.key): \(String(describing: snapshot.value))")
    }
    //---------------------------------------
    
    drivingTowardsRef.observe(.childAdded) { snapshot in
        ref.child(snapshot.key).getData { (error, userSnapshot) in
            if let error = error {
                print(error)
            } else {
                print("Got arriving user data \(snapshot.key): \(String(describing: userSnapshot.value))")
            }
        }
    }
}

该函数将只返回整个数据库数据 编辑:该函数返回来自第一个观察者参考顶层的数据,在这种情况下用户/在我的情况下有两个元素:niixi6iORjNn8gWq6tKvSi3Bxfc2,u3Ebr6M3BAbP7PBSYYJ7q9kEe1l2

Got arriving user data niixi6iORjNn8gWq6tKvSi3Bxfc2: Optional({
niixi6iORjNn8gWq6tKvSi3Bxfc2 =     {
    aproxTime = 0;
    distance = 0;
    latitude = "37.33070704";
    longitude = "-122.03039943";
    parkingMode = searching;
    userId = niixi6iORjNn8gWq6tKvSi3Bxfc2;
    username = testeroNumero;
};
u3Ebr6M3BAbP7PBSYYJ7q9kEe1l2 =     {
    aproxTime = 0;
    distance = 0;
    drivingTowardsUsers =         {
        niixi6iORjNn8gWq6tKvSi3Bxfc2 =             {
            approxTime = 0;
            distance = "560.1447571016249";
        };
    };
    latitude = "37.32984184";
    longitude = "-122.02018095";
    parkingMode = offering;
    userId = u3Ebr6M3BAbP7PBSYYJ7q9kEe1l2;
    username = cleoBadu;
};

我通过他的子路径的关键似乎是正确的,但它仍然返回整个顶级集合而不是单个项目......

编辑:问题似乎出在第一个观察者身上,它弄乱了 ref.child(snapshot.key) 的 .getData()。这甚至可能吗?

只需注释掉 ref.observe(.childAdded) 就会自动使第二个 ref.child(snapshot.key) 行为完全正常我错过了什么?

我可以将整个数据库作为一个大型词典获取,然后从那里获取我想要的孩子,但这似乎并不传统,尤其是当谷歌的图书馆提供不这样做的可能性时。

编辑:我添加了一个打印语句,打印数据库引用的 url。如果我随后在浏览器上输入 url,它会将我重定向到 FRT 数据库并让我登陆正确的对象。所以它生成的 url 是正确的并且工作得很好。getData() 返回的对象仍然是整个数据库

SN:我删除了所有可编码的结构,因为这不是问题,所以问题更关注实际问题

编辑:创建了一个简单的视图。在一个干净的项目上它适用于我的项目它没有。我想这是某种配置,但很难研究它。

问题:无论我传递给他什么孩子(字符串),它都会以任何一种方式返回整个顶级数据(替换快照.key)。例如:我传递key“something”->返回所有用户,我传递key“”返回所有用户

标签: swiftfirebasefirebase-realtime-database

解决方案


我只是试图用(大部分)您的代码和数据重现问题,但没有得到相同的行为。

我将等效数据放入我的数据库中:https ://stackoverflow.firebaseio.com/68956236.json?print=pretty

并在 Xcode 1.2 和 Firebase SDK 版本 8.6.1 中使用此代码:

let ref: DatabaseReference = Database.database().reference().child("68956236")
let currentUserId: String = "u3Ebr6M3BAbP7PBSYYJ7q9kEe1l2"

let drivingTowardsRef: DatabaseReference! = ref.child("\(currentUserId)/drivingTowardsUsers");
print("Loading data from \(drivingTowardsRef)")

drivingTowardsRef.observe(.childAdded) { snapshot in
    ref.child(snapshot.key).getData { (error, userSnapshot) in
        if let error = error {
            print(error)
        } else {
        
            do {
                //let parkingUser =  try userSnapshot.data(as: ParkingUser.self)
                print("Got data for user \(snapshot.key): \(String(describing: userSnapshot.value))")
            } catch {
                print("There has been an error while decoding the user location data with uid \(snapshot.key), the object to be decoded was \(userSnapshot). The decode failed with error: \(error)")
            }
        }
    }
}

我得到的输出是:

从可选加载数据(https://stackoverflow.firebaseio.com/68956236/u3Ebr6M3BAbP7PBSYYJ7q9kEe1l2/drivingTowardsUsers

2021-08-27 10:39:09.578043-0700 Firebase10 [36407:3458780] [] nw_protocol_get_quic_image_block_invoke dlopen libquic 失败

获取用户 niixi6iORjNn8gWq6tKvSi3Bxfc2 的数据:可选({ aproxTime = 0;距离 = 0;纬度 =“37.32798355”;经度 =“-122.01982712”;parkingMode = 搜索;用户 ID = niixi6iORjNn8gWq6tKvSi3Bxfc2;用户名 = testeroNumero;

据我所知,这种行为是正确的,但与你得到的不同。我希望知道我没有看到相同的行为以及我使用的版本可能对您有所帮助。


推荐阅读