AngularFire2针对可怜的Firebase数据模型的解决方法

时间:2018-01-05 20:05:39

标签: firebase angularfire angularfire2

我刚刚推出了一个使用Firebase作为数据存储的移动应用,我有一个类似的RTDB集合:

classes:{
"-Kv4KCJM4rHbwqF-pMxN":
{
  "added" : 1515114635871,
  "admins" : {
    "wgKCoCZj4IaWuiwGKwygpEZ3sg02" : true
  },
  "allowConversations" : false,
  "grade" : 998,
  "name" : "Some Name",
  "pageContent" : "Possibly VERY LARGE field",
  "school" : "-KufLJxgD8DE2FnutPbs"
},

  "-KvEpubNdVvlnSsKJ4Z9": {
  "added" : 1515114635871,
  "admins" : {
    "wgKCoCZj4IaWuiwGKwygpEZ3sg02" : true
  },
  "allowConversations" : false,
  "grade" : 998,
  "name" : "Name",
  "pageContent" : "Possibly VERY LARGE field",
  "school" : "-KufLJxgD8DE2FnutPbs"
}
...
}

我需要加载此集合,仅用于构建移动应用中的链接列表。问题是pageContent可能非常大,几MB,因为base64图像是内联的。最终我会将pageContent移到一个单独的集合中,但我需要一个短期修复,因为这每天都会耗尽Firebase的GB带宽!

要构建链接列表,我只需要id(密钥),名称和成绩字段。我正在使用angularfire2,所以我这样做:

getClasses2(): Promise<any> {
let _thee = this;
return new Promise((resolve, reject) => {
  if (Object.keys(_thee._classesData).length > 0) {
    return resolve(_thee._classesData);
  }

  let classList = _thee.afDB.list(`/schools/${this.schoolid}/classes`).valueChanges();

  classList.subscribe(aClass => {
    console.log(aClass);
    aClass.forEach((c: string, i) => {
      _thee._classesData[c].id = c;
      this.afDB
        .object(`/classes/${c}/grade`)
        .valueChanges()
        .subscribe(grade => {
          _thee._classesData[c].grade = grade;
        });
      this.afDB
        .object(`/classes/${c}/name`)
        .valueChanges()
        .subscribe(name => {
          _thee._classesData[c].name = name;
        });
      if (i + 1 === aClass.length) {
        return resolve(_thee._classesData);
      }
    });
  });
});

}

问题是在承诺中处理这两个Observable。理想情况下,observable只是做他们的事情,并且完全异步更新_classesData中的相应对象,当for循环结束时,我解决了promise,而_classesData&#39;可能会&#39;仍然会被观察者更新,但那没关系。问题是这看起来像垃圾,是垃圾,即使这是非常短期的并且将在几天内被替换,我仍然需要控制数百个移动设备的带宽使用量,访问50-60Mb的数据几百次一天。

是否有一种优雅的方法可以使用AngularFire2方法正确访问对象中的两个属性,同时保持一定程度的同步?

1 个答案:

答案 0 :(得分:0)

我认为您需要从包含数据信息中拆分描述信息。例如,从pageContent移除classes并创建一个pageContent文档来保存它。

因为当您请求/schools/${this.schoolid}/classes时,您将获得所有 classes信息。如果有任何变化(在任何课程中),您将再次获得整个数据(不仅仅是更改的类或更改的值)。

另一点是,也许您应该考虑分散数据库。例如,您可以在classes内部使用SchoolName,而不仅仅是"school" : "-KufLJxgD8DE2FnutPbs"

最后一个想法是,您可以考虑使用Firebase once()或Observable ...take(1).subscribe()