【问题标题】:Firebase's ref().child(stringPath: String) returning the entire top level collectionFirebase 的 ref().child(stringPath: String) 返回整个顶级集合
【发布时间】:2021-08-27 15:49:56
【问题描述】:

我正在尝试使用 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))")
            }
        }
    }
}

该函数只会返回整个数据库数据 编辑:在这种情况下,该函数返回来自第一个观察者参考顶层的数据 users/ 在我的情况下有两个元素: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) 行为完全正常 我错过了什么?

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

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

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

EDIT:创建了一个简单的视图。在一个干净的项目上它适用于我的项目它没有。我猜这是某种配置,但很难调查。

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

【问题讨论】:

  • 你能把完整的代码贴出来吗?
  • 添加完整代码
  • 在图片中发布 ParkingUser Codable 结构和您的 firebase 结构
  • 还添加了可编码结构
  • 我尝试重现该问题,但无法重现。由于信息太长,无法发表评论,我将其写在下面作为答案。

标签: swift firebase firebase-realtime-database


【解决方案1】:

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

我将等效数据放入我的数据库中: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)")
            }
        }
    }
}

我得到的输出是:

从 Optional(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 的数据:可选({ 近似时间 = 0; 距离 = 0; 纬度=“37.32798355”; 经度=“-122.01982712”; 停车模式=搜索; userId = niixi6iORjNn8gWq6tKvSi3Bxfc2; 用户名 = testeroNumero; })

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

【讨论】:

  • 您好,非常感谢您花时间重现它!是孩子(“68956236”)吗?您专门为测试制作的子集合?
  • Firebase 的实时数据库中没有集合/子集合的概念,但 68956236 确实是我数据库中用于此测试的一个节点(它是您问题的 ID)。您可以在我在问题中添加的链接中看到节点的内容,因为我将其设为公开可读。
  • 我尝试更新到 8.6.1 我正在尝试 rn 重现 vanilla 项目中的错误,如果它仍然存在,我将尝试编辑我的帖子添加 GitHub 链接
  • 我认为这里不需要更多代码。我宁愿你尝试用尽可能少的代码和数据来重现它,就像我在我的帖子中所做的那样。例如:如果你得到错误的数据,Codable 类应该无关紧要——这就是为什么我只是从数据快照中打印值,甚至从未使用过ParkingUser。更少的代码使我们更有可能看到相同的东西。我通常会推荐一种倒置的方法:首先尝试使用我的代码获得一个可以工作的迷你应用程序,然后看看你是否能像你的问题中发生的那样破坏它。
  • 我认为发生这种情况是因为 Codable 期望值为 Double 但 firebase 返回一个字符串?
【解决方案2】:

这不是 Firebase 的问题,而是客户端处理返回的数据,您希望 Codable 结构中有一个 Double ,但在另一端提供一个字符串 - 您可以试试吗:

public struct ParkingUser: Codable {
    var latitude: String
    var longitude: String
}

【讨论】:

  • 我删除了所有可编码的结构和解码语句,因为问题不存在。我更新了这个问题,它更干净、更集中。非常感谢
猜你喜欢
  • 2021-09-21
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
相关资源
最近更新 更多