【问题标题】:Reading data from Firebase RTDB using Flutter has different behavior on Android and iOS使用 Flutter 从 Firebase RTDB 读取数据在 Android 和 iOS 上具有不同的行为
【发布时间】:2022-02-24 08:33:19
【问题描述】:

我遇到了以下调用在针对 iOS 和 Android 执行时表现不同的行为。

在 Android 中,以下 .get() 调用从 chatRoomID 路径返回预期的快照。但是,在 iOS 中,.get() 最终会返回 myUser.userID 下整个节点的快照。

似乎对于iOS,第二个子节点路径被忽略了......

DataSnapshot snapshot = await chatsRef
                          .child(myUser.userID!)
                          .child(chatRoomID)
                          .get();
print(snapshot.value);

JSON:

{
"chats" : {
  "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1" : {
    "c00dca80-9077-11ec-855a-910961fc4253" : {
      "chatAdmin" : "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1",
      "chatImage" : "https://images.pexels.com/photos/887827/pexels-photo-887827.jpeg?auto=compress&cs=tinysrgb&h=650&w=940",
      "chatName" : "chef",
      "chatRoomID" : "c00dca80-9077-11ec-855a-910961fc4253",
      "isActivityChat" : false,
      "isGroupChat" : true,
      "lastMessage" : {
        "lastMessage" : "Hey",
        "lastMessageTime" : "2022-02-18 00:00:56.992308",
        "messageID" : "-MwAC5BUz3GKPmkA1SSQ",
        "nKDsrLrcU0PgtEDV5tKpMumSDuu1" : "true",
        "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1" : "false",
        "psJQRp96VGWIjTDpNpMUShPNWa82" : "true",
        "sendBy" : "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1",
        "senderName" : "Emily"
      },
      "muted" : {
        "nKDsrLrcU0PgtEDV5tKpMumSDuu1" : false,
        "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1" : false,
        "psJQRp96VGWIjTDpNpMUShPNWa82" : false
      },
      "users" : {
        "nKDsrLrcU0PgtEDV5tKpMumSDuu1" : true,
        "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1" : true,
        "psJQRp96VGWIjTDpNpMUShPNWa82" : true
      }
    },
    "nKDsrLrcU0PgtEDV5tKpMumSDuu1_oF1b6J4Hz3NGzRb9RmSVFGJdcYi1" : {
      "chatRoomID" : "nKDsrLrcU0PgtEDV5tKpMumSDuu1_oF1b6J4Hz3NGzRb9RmSVFGJdcYi1",
      "isActivityChat" : false,
      "isGroupChat" : false,
      "lastMessage" : {
        "lastMessage" : "Shut",
        "lastMessageTime" : "2022-02-18 00:01:30.161511",
        "messageID" : "-MwACDHlTWpQhhQFh9k8",
        "nKDsrLrcU0PgtEDV5tKpMumSDuu1" : "true",
        "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1" : "false",
        "sendBy" : "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1",
        "senderName" : "Emily"
      },
      "muted" : {
        "nKDsrLrcU0PgtEDV5tKpMumSDuu1" : false,
        "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1" : false
      },
      "users" : {
        "nKDsrLrcU0PgtEDV5tKpMumSDuu1" : true,
        "oF1b6J4Hz3NGzRb9RmSVFGJdcYi1" : true
      }
    }
  }
},
}

【问题讨论】:

  • 嗯...这听起来确实很奇怪,因为底层 SDK 在这些平台上应该可以正常工作。您可以将您的问题编辑为: 1) 将 JSON 作为文本包含在内,以便我可以将其复制/粘贴到我自己的数据库中进行测试?您可以通过单击Firebase Database console 上溢出菜单 (⠇) 中的“导出 JSON”链接来获取此信息。 2) 显示单个代码 sn-p,我可以将其复制/粘贴到我的 Flutter 测试平台中以重现问题?
  • 嗨弗兰克,我刚刚编辑了我的问题。我发现 iOS 和 Android 之间不同的另一个行为是,每当我检查一个节点是否有一个子节点时,iOS 总是返回有一个子节点,即使 Android 没有正确执行它也是如此。基本上 Firebase SDK 的工作方式与我期望它在 Android 上的表现完全一样,但在 iOS 上的表现却不同...... await chatsRef.child(myUser.userID!).child(chatRoomID).get().then((DataSnapshot 快照) async {if (snapshot.value == null) {...then do A}}
  • 嘿@ckingprogramming。感谢分享 JSON ????。很遗憾听到第二个问题,但我现在想专注于第一个问题。我们的一位工程师试图在纯 iOS SDK 中重现它,但未能成功。我可以在 Flutter 中尝试一下,但这需要一些时间。您能否将代码更改为记录 iOS 和 Android 之间不同输出的代码,然后在您的问题中包含更新后的代码及其输出。
  • 嗨弗兰克,在进一步调试我遇到的初始问题和我观察到的第二个问题后,我意识到它们基本上是由以下代码行引起的相同问题:DataSnapshot snapshot = await chatsRef.child (myUser.userID!).child(chatRoomID).get();我更新了问题以更好地描述问题。
  • 弗兰克!事实证明,它确实与 get, once 工作得很好。感谢您的建议。

标签: ios flutter firebase-realtime-database


【解决方案1】:

如 cmets 中所述

您应该在 iOS 和 Android 上获得相同的行为,因为底层 SDK 在这些平台上的工作方式应该相同。也就是说,由于 FlutterFire 库封装了原生 SDK 并且 get() API 相对较新,因此 iOS 和 Android SDK 的实现方式可能存在意想不到的差异。

如果确实如此,您可能想试试看once() 是否适合您。虽然它在边缘情况下会产生烦人的副作用(请参阅 here),但 once API 本身要旧得多,因此更可能跨平台保持稳定。


更新:我很难重现这个问题。我已将您的 JSON 导入我的数据库,然后在我的应用启动时运行此代码:

FirebaseDatabase database = FirebaseDatabase.instance;
var chatsRef = database.ref('71163140/chats');
var threadRef = chatsRef.child('oF1b6J4Hz3NGzRb9RmSVFGJdcYi1').child('nKDsrLrcU0PgtEDV5tKpMumSDuu1_oF1b6J4Hz3NGzRb9RmSVFGJdcYi1');
DataSnapshot snapshot = await threadRef.get();
if (snapshot.value != null) {
  print('get: ${snapshot.value}');
}

DatabaseEvent event = await threadRef.once();
if (event.snapshot.value != null) {
  print('once: ${event.snapshot.value}');
}

因此,它会从您与get()once() 共享的数据中读取一个聊天线程,然后打印它获得的内容。在 iOS 和 Android 上,我从未在输出中看到 c00dca80-9077-11ec-855a-910961fc4253 线程,我只看到 "isGroupChat" : false, 的聊天线程。

您能否更新问题中的代码或数据,以说明我如何获得与您相同的错误结果?

【讨论】:

  • 嗨弗兰克,代码和 JSON 可能不是问题,因为我从您发布的代码中看不到任何与我不同的内容。我想知道是不是因为我使用的是较旧的 firebase_database 插件版本。我目前正在使用 firebase_database: ^8.2.0.我拒绝更新到新的插件版本,因为有很多重大变化。
  • 我认为 SDK 的这一部分最近没有变化,但如果升级到最新的库版本后问题是否消失,请告诉我。
猜你喜欢
  • 2020-12-18
  • 2022-06-27
  • 2020-09-06
  • 2020-09-17
  • 2017-03-01
  • 2020-05-05
  • 2020-04-18
  • 2020-09-18
  • 2019-05-31
相关资源
最近更新 更多