按Firebase

时间:2016-10-27 13:02:38

标签: firebase firebase-realtime-database

我通过REST API使用Firebase。我有以下数据库结构:

{
  "categories" : {
    "Cat1" : {},
    "Cat2" : {},
    "Cat3" : {},
    "Cat4" : {}
  },

  "items" : {
    "item1" : {
      "categories": ["Cat1", "Cat3"]
    },
    "item2" : {
      "categories": ["Cat1", "Cat3"]
    },
    "item3" : {
      "categories": ["Cat1", "Cat2", "Cat3"]
    },
    "item4" : {
      "categories": ["Cat4"]
    }
  }
}

正如您所看到的,我们在类别和项目之间存在类型“N< - > N”的关系(一个类别可以包含多个项目,一个项目可以在多个类别中)。

现在我想通过Firebase REST API获取Cat1的所有项目,但我不能这样做。

我们知道数组存储在Firebase中,就像带有整数索引的地图一样:

"categories": {
  "0": "Cat1",
  "1": "Cat2",
  "2": "Cat3",
}

因此,我将".indexOn": ["categories/*"]添加到实时数据库规则并试图将其称为:
curl 'https://...firebaseio.com/...json?orderBy="categories/*"&equalTo="Cat1"'

但我只得到了这个:{ }

所以,我认为正则表达式在Firebase查询中不起作用,因为这有效:
实时数据库规则中的".indexOn": ["categories/0"]
curl 'https://...firebaseio.com/...json?orderBy="categories/0"&equalTo="Cat1"'

当然,我可以将数据库模型更改为:

{
  "categories" : {
    "Cat1" : {},
    "Cat2" : {},
    "Cat3" : {},
    "Cat4" : {}
  },

  "items" : {
    "item1" : {},
    "item2" : {},
    "item3" : {},
    "item4" : {}
  },

  "category-items": {
    "Cat1": ["item1", "item2", "item3"],
    "Cat2": ["item3"],
    "Cat3": ["item1", "item2", "item3"]
    "Cat4": ["item4"]
  }
}

获取category-items并遍历Cat1数组,但是我必须多次调用REST API读取方法(对类别中的每个item调用一次REST API )。所以,它太贵了。

那么,有人可以帮助我在原始数据库模型中获取某个类别中的所有项目吗?

更新
最终的模型是:

{
  "categories" : {
    "Cat1" : {},
    "Cat2" : {},
    "Cat3" : {},
    "Cat4" : {}
  },

  "items" : {
    "item1" : {
      "Cat1": true,
      "Cat3": true,
    },
    "item2" : {
      "Cat1": true,
      "Cat3": true,
    },
    "item3" : {
      "Cat1": true,
      "Cat2": true,
      "Cat3": true,
    },
    "item4" : {
      "Cat4": true
    }
  }
}

我也添加了

{
  rules": {
    ...
    "items": {
      ".indexOn": [ "Cat1", "Cat2", "Cat3", "Cat4" ]
    }
  }
}

到实时数据库规则,REST API调用是
curl 'https://...firebaseio.com/items.json?orderBy="Cat1"&equalTo=tr‌​ue'

感谢Vladimir Gabrielyan

2 个答案:

答案 0 :(得分:2)

这是我建议的结构。

{
  "categories" : {
    "Cat1" : {
        "items": {
            "item1":{/*Some item info*/},
            "item2":{/*Some item info*/}
        }
    },
    "Cat2" : {
        "items": {
            "item3":{/*Some item info*/}
        }
    },
  },

  "items" : {
    "item1" : {
      "categories": {
          "Cat1": true,
      }
    },
    "item3" : {
      "categories": {
          "Cat2": true, 
          "Cat3": true
      }
    }
  }
}

Cat1/Items/{itemId}和items/{itemId}内,您需要复制item信息,但我认为没问题。

另见本文。 https://firebase.googleblog.com/2013/04/denormalizing-your-data-is-normal.html

答案 1 :(得分:0)

哇!非常感谢你!你的建议是替换

"item1" : {
  "categories": ["Cat1", "Cat3"]
},

"item1" : {
  "Cat1": true,
  "Cat3": true
},

可以解决问题,但是我必须在实时数据库规则中将每个Cat添加到.indexOn,但这不是原始问题的大问题。

但我认为

"categories" : {
  "Cat1" : {
    "items": {
        "item1":{/*Some item info*/},
        "item2":{/*Some item info*/}
    }
  },
  "Cat2" : {
    "items": {
        "item3":{/*Some item info*/}
    }
  },
}

在我的案例中不是一个好主意,因为每当我们获得有关Cat的信息时,我们会获得许多备用数据(当我们不需要项目列表时,只需要Cat的元数据)。所以,我建议遵循以下模型:

{
  "categories" : {
    "Cat1" : {},
    "Cat2" : {},
    "Cat3" : {},
    "Cat4" : {}
  },

  "items" : {
    "item1" : {
      "Cat1": true,
      "Cat3": true,
    },
    "item2" : {
      "Cat1": true,
      "Cat3": true,
    },
    "item3" : {
      "Cat1": true,
      "Cat2": true,
      "Cat3": true,
    },
    "item4" : {
      "Cat4": true
    }
  }
}