【问题标题】:Firebase count ChildrenFirebase 计数儿童
【发布时间】:2017-02-10 11:35:03
【问题描述】:

Firebase 数据:

{
    "data": {
        "entry-1": {
            "created": 1484634400,
            "status": 1
        },
        "entry-2": {
            "created": 1482612312,
            "status": 0
        },
        "entry-3": {
            "created": 1481623400,
            "status": 1
        },
        "entry-4": {
            "created": 1485613233,
            "status": 1
        },
        "entry-5": {
            "created": 1489513532,
            "status": 0
        },
        "entry-6": {
            "created": 1483123532,
            "status": 1
        },
        "entry-7": {
            "created": 1481282376,
            "status": 1
        },
        "entry-8": {
            "created": 1432321336,
            "status": 1
        },
        "entry-9": {
            "created": 1464282376,
            "status": 0
        }
    }
}

我正在尝试计算在entry-4 之前创建了多少活动条目 (status = 1),并实时更新计数。

今天我听数据库的每一个变化,但它消耗了大量不必要的数据。有没有更好的方法来做到这一点?


代码:

FIRDatabaseQuery *query = [self.firebase child:@"data"];
[query observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
    int count = 0;
    for (FIRDataSnapshot *child in snapshot.children) {
        if (child.value[@"status"] == 1 && child.value[@"created"] < 1485613233) {
             count++;
        }
    }
}];

【问题讨论】:

  • Firebase 数据库中没有计数运算符。为了避免必须下载所有项目来获得计数,您可以保留一个单独的 count 节点 - 然后您可以通过事务进行更新。见stackoverflow.com/questions/15148803/…
  • Firebase 最近发布了 Cloud Functions。看看这个answer了解更多详情

标签: ios objective-c firebase firebase-realtime-database


【解决方案1】:

我提供了一个 Swifty 的答案,但它很容易转换为 Obj-C

把你的数据结构改成这个

{
    "data": {
        "-Yuna99s993m": {
            "created": 1484634400,
            "status": "1"
            "entry": "1"
            "status_entry": "1_1"
        },
        "-YUjns0909ks": {
            "created": 1482612312,
            "status": "0"
            "entry": "2"
            "status_entry": "0_2"
        },
        "-Y8hj98nmswm": {
            "created": 1481623400,
            "status": "1"
            "entry": "3"
            "status_entry": "1_3"
        },
        "-Y78903kjmsk": {
            "created": 1485613233,
            "status": "1"
            "entry": "4"
            "status_entry": "1_4"
        },
        "-YJuikw9klkos": {
            "created": 1489513532,
            "status": 0
            "entry": "5"
            "status_entry": "0_5"
        },

然后是一个查询来检索 4 之前的所有条目,状态为 1

let dataRef = ref.child("data")
let queryRef1 = dataRef.queryOrdered(byChild: "status_entry")
let queryRef2 = queryRef1.queryStarting(atValue: "1_1")
                         .queryEnding(atValue: "1_3")
queryRef2.observeSingleEvent(of: .value, with: { snapshot in
   print(snapshot.childrenCount) 
 })

运行时返回

2

这意味着条目 4 之前有两个节点的状态为 1;这些节点是

"-Yuna99s993m": {
  "created": 1484634400,
  "status": "1"
  "entry": "1"
  "status_entry": "1_1"
"-Y8hj98nmswm": {
  "created": 1481623400,
  "status": "1"
  "entry": "3"
  "status_entry": "1_3"

*像“-Yuna99s993m”这样的节点名称是使用 childByAutoId 创建的 - 通常最好的做法是将节点键名称与它们包含的子数据分离。

这里的思考过程是通过将两个变量entry#和status组合成一个变量status_entry,我们限制了startingAt和endingAt返回的内容。所以 1_x 将消除所有的 0_ 状态,我们通过指定从 x_1 到 x_3 的条目来进一步限制返回的节点。

诀窍是在 x_4 之前获取节点,因为那将是 .endingAt。如果它总是 x_3 那就很简单了。

【讨论】:

    猜你喜欢
    • 2018-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多