【问题标题】:Maximum number of roundtrips for pushing to a list of data in Firebase Real Time Database?推送到 Firebase 实时数据库中的数据列表的最大往返次数?
【发布时间】:2018-05-03 21:14:35
【问题描述】:

在我的 Angular 4 应用程序中,我使用 push() 方法将数据附加到 Firebase 实时数据库中的数据列表中。请参阅 Firebase 文档:https://firebase.google.com/docs/database/web/lists-of-data

每次将新子项添加到指定的 Firebase 引用时,push() 方法都会生成一个唯一键。这是一个数组“市场”,由 250 个对象组成,键为 symbol、price、balance

market = [
  { symbol: '1ST', price_usd: 1, balance: 100},
  { symbol: '2ND', price_usd: 2, balance: 300},
  { symbol: '3RD', price_usd: 3, balance: 400}
  // etc etc for a total of 250 objects
];

我在 Angular 4 组件中编写了以下代码:

import {AngularFireDatabase} from 'angularfire2/database';
import * as firebase from 'firebase';

constructor(private db: AngularFireDatabase) {}

storeTicker() {
  const timestamp = firebase.database.ServerValue.TIMESTAMP;
  for (let object of market) {
    const path = object['symbol'];
    const itemsRef = this.db.list('Tickers/' + path);
    itemsRef.push({ symbol: path, price_usd: object['price_usd'], balance: object['balance'], time: timestamp});
  }
}

当点击按钮时执行代码,这将导致每个引用的时间序列。

我的 Firebase 实时数据库如下所示:

{ "Tickers" : {
    "1ST" : {
      "-Kx8gN5uZALd5BP2GCH6" : {
        "balance" : 0,
        "price_usd" : 0.25583,
        "symbol" : "1ST",
        "time" : 1508769890908
       }},
    "2ND" : {
      "-Kx8Z0xCl7ONZERk1ICo" : {
        "balance" : 0,
        "price_usd" : 0.0253829,
        "symbol" : "2ND",
        "time" : 1508769890908
      }},
    "3RD" : {
      "-Kx8gN5FEZEPsOe8S-Tw" : {
        "balance" : 0,
        "price_usd" : 0.767354,
        "symbol" : "3RD",
        "time" : 1508769890908
    }},
  // for a  total of 250 paths
}}

以这种方式对push() 的每次调用都会导致到 Firebase 的往返。问题是 Firebase 只对前 100 个引用执行 push()

我在 Firebase 文档中找不到往返次数的限制:https://firebase.google.com/docs/database/usage/limits

我在 Stackoverflow Adding list of data in Firebase 上发现了一个类似问题的问题,但我不明白更新部分。

我的两个问题是:

  1. Firebase 中是否存在最大往返次数或是否存在其他错误?

  2. 如何通过将代码组合到多位置更新中来使代码正常工作?

【问题讨论】:

  • 我不确定我是否理解问题所在。代码不行吗?
  • 代码有效,但 Firebase 在对象 nr 100 处停止:它只存储我的 250 个 Array 对象中的前 100 个。我最近才发现这个问题,我的数组以前是50个对象。
  • 嗯...这听起来令人惊讶。你能在 jsbin 中重现它,让我看看吗?
  • 我对 Angular4 很陌生,但我试图在 Plunker 中重现它:plnkr.co/edit/cPxdNsvEl25ipyhbGJJj?p=preview plunker 没有加载,我不完全理解所有 Angular 配置部分,但至少我的代码在那里,也许这有助于看看?

标签: angular typescript firebase firebase-realtime-database angularfire2


【解决方案1】:

使用不带参数的push() 方法将在本地生成唯一ID,并且不会导致对数据库的网络操作:

如果您向push() 提供值,则该值将写入 生成的位置。如果您不传递值,则不会写入任何内容 到数据库,孩子将保持为空(但您可以使用 Reference 其他地方)。

因此,您可以使用它为您需要推送到数据库的每个项目获取唯一 ID,将其存储在一个数组中,然后使用 update() 在多位置更新中同时将所有项目发送到数据库,类似:

storeTicker() {
  const timestamp = firebase.database.ServerValue.TIMESTAMP;
  var updates = {};
  for (let object of market) {
    const key = this.db.list('/Tickers').push().key; // Get a new unique key (locally, no network activity)
    const path = object['symbol'] + '/' + key;
    updates[path] = {symbol: object['symbol'], price_usd: object['price_usd'], balance: object['balance'], time: timestamp};
  }
  this.db.object('/Tickers').update(updates);
}

update() 方法(类似于官方的Firebase JavaScript SDK update() method)的工作原理是将整个数组发送到指定位置:

values 参数包含将一起写入数据库的多个属性值对。每个子属性可以是简单的属性(例如,“name”),也可以是从当前位置到要更新的数据的相对路径(例如,“name/first”)。

有关这方面的文档示例,请参阅 updating data using AngularFireupdate specific fields using the JavaScript SDK

【讨论】:

  • 我在 CLI 中编译失败:“提供的参数与调用目标的任何签名都不匹配”在最后部分 tickersRef.update(updates);
  • @Ianvh 抱歉,tickersRef 变量应该是 this.db.object('/Tickers')(根据 angularfire2 Multi-path update),请参阅我的编辑。
  • 它在生成唯一键的行上出现错误:“AngularFireObject 类型上不存在属性'push'”。例如,当我将 const 键手动更改为“test”之类的字符串时,代码运行并生成一个对象对象,但数据未存储在数据库中。这是因为 tickersRef 是 AngularFireDatabase 服务吗?
  • @Ianvh 好的,您可以完全删除 tickersRef 变量。 AngularFire 的行为似乎与官方的 Firebase JavaScript SDK 不同,这令人困惑。 AngularFire update() method 应该是一样的。我又更新了答案。
  • 少一个问题,可以用const key = this.db.createPushId()生成唯一密钥。但是最后一行仍然没有更新数据库。我尝试了像link 这样的回调来检测错误,但这也不起作用。关于如何通过浏览器开发工具调试或找出错误的任何想法?
猜你喜欢
  • 2020-03-25
  • 2021-08-28
  • 2013-02-12
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-05
  • 2012-05-16
相关资源
最近更新 更多