Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
632 views
in Technique[技术] by (71.8m points)

firebase - 如何使用查询或特定路径从Firebase实时数据库有效查询(How to efficiently query from Firebase Realtime Database using query or specific path)

We have infrequently property modification("price") on Firebase Realtime Database which is structure like this:

(我们很少在Firebase Realtime数据库上进行如下属性修改(“ price”):)

../currencies/<currency>/value/
      "price":343

every player that log in will listen to only one and specific currency.

(每个登录的玩家只会听一种特定的货币。)

our client will pick the right currency path based on the player preferences.

(我们的客户将根据玩家的偏好选择正确的货币路径。)

so if player is set to currency USD the firebase client will listen to this path

(因此,如果玩家将币种设置为货币USD,则Firebase客户端将侦听此路径)

../currencies/USD/value/
      "price":343

Those currencies prices are changed infrequently

(这些货币的价格很少变动)
due to this structure our server side need to modify and denormalized the data to all currencies when it changes (we can have ten's of currencies) because of that we add to the leaf even more properties which are identical at all currencies

(由于这种结构,我们的服务器端需要在数据更改时将其修改并归一化为所有货币(我们可以拥有十个货币),因为我们向叶中添加了更多在所有货币上都相同的属性)

which I find redudent like:

(我发现像这样的冗余:)

../currencies/USD/value/
          "price":343
          "currency-source":"fx" . //this property will be copied to all 

currencies vals because the client listen to only one path and it needs this data aswell

(货币vals,因为客户端仅侦听一条路径,并且它也需要此数据)

instead if manitain this on path's perhaps we can use some query where each client will be able to pick it's currency based on property name?

(取而代之的是,如果在路径上进行manitain操作,我们可以使用一些查询,使每个客户都可以根据属性名称选择其货币?)

something like that:

(像这样的东西:)

../currencies/value/
          "USD_price":343
          "EUR_price":343
      ...

thoughts about design?

(关于设计的想法?)

and if sounds better how can be achieved with Firebase Realtime Database query?

(如果听起来更好,如何使用Firebase实时数据库查询来实现?)

  ask by rayman translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't know which language (which Client SDK) you use in your app, but here is a solution with the JavaScript SDK.

(我不知道您在应用中使用哪种语言(哪种客户端SDK),但这是JavaScript SDK的解决方案。)

Let's imagine you have a Relatime Database structure as follows

(假设您有一个Relatime数据库结构,如下所示)

  "parentnode" : {
    "currencies" : {
      "EUR" : {
        "value" : {
          "price" : 201
        }
      },
      "USD" : {
        "value" : {
          "price" : 343
        }
      },
      "value" : {
        "EUR_price" : 201,
        "USD_price" : 343,
        "currency-source" : "fx"
      }
    }
  }

Under a parentnode you have a currencies node which corresponds to the examples in your question .

(在parentnode节点下您有一个currencies节点,该节点与问题中的示例相对应 。)

In case you want to listen to /currencies/<currency>/value , you would do as follows:

(如果您想收听/currencies/<currency>/value ,请执行以下操作:)

  var db = firebase.database();

  var currency = 'EUR';

  var ref = db.ref().child('parentnode/currencies/' + currency);
  ref.on('value', function(snapshot) {
    var data = snapshot.val();
    console.log(data);
  });

In case you want to listen to /currencies/value/<currency>_price and get the price and the currency-source values, you would do as follows:

(如果您想收听/currencies/value/<currency>_price并获取pricecurrency-source值,请执行以下操作:)

  var db = firebase.database();

  var currency = 'EUR';

  var ref = db.ref().child('parentnode/currencies/value');
  ref.on('value', function(snapshot) {
    var data = snapshot.val();
    var price = data[currency + '_price'];
    var source = data['currency-source'];
    console.log(price);
    console.log(source);
  });

As mentioned in your comment, the second approach implies that "we will download all the data leaf under /currencies/value/ ".

(如您的评论中所述,第二种方法意味着“我们将在/currencies/value/下下载所有数据叶”。)

I can think of two other possible approaches.

(我可以想到另外两种可能的方法。)

Choosing one over the other really depends on your functional requirements, ie what you do with these values in your front-end.

(一个选择另一个实际上取决于您的功能要求,即您在前端中如何使用这些值。)

1/ Set two listeners (1 /设置两个听众)

The idea is to set one listener for 'parentnode/currencies/value/' + currency + '_price' and one for 'parentnode/currencies/value/currency-source' , as follows:

(想法是为'parentnode/currencies/value/' + currency + '_price'设置一个侦听器,为'parentnode/currencies/value/currency-source'设置一个侦听器,如下所示:)

  var currency = 'EUR';

  var ref2 = db
    .ref()
    .child('parentnode/currencies/value/' + currency + '_price');
  ref2.on('value', function(snapshot) {
    var data = snapshot.val();
    console.log(data);
  });

  var ref3 = db.ref().child('parentnode/currencies/value/currency-source');
  ref3.on('value', function(snapshot) {
    var data = snapshot.val();
    console.log(data);
  });

2/ Query the currency-source value within the listener (2 /在侦听器中查询currency-source值)

With this second approach, in the listener to 'parentnode/currencies/value/' + currency + '_price' , we query the database with the once() method to get the value of currency-source :

(通过第二种方法,在侦听'parentnode/currencies/value/' + currency + '_price' ,我们使用'parentnode/currencies/value/' + currency + '_price' once()方法查询数据库以获取currency-source的值:)

  var ref4 = db
    .ref()
    .child('parentnode/currencies/value/' + currency + '_price');
  ref4.on('value', function(snapshot) {
    var data = snapshot.val();
    console.log(data);
    db.ref()
      .child('parentnode/currencies/value/currency-source')
      .once('value')
      .then(function(dataSnapshot) {
        console.log(dataSnapshot.val());
      });
  });

Note that if do not need to set a listener, ie you want to fetch the data once (eg by triggering the fetch from a button, or on page loading, etc..) you should only use the once() method and then you can chain the two calls as follows:

(请注意,如果不需要设置侦听器,即您想一次获取数据 (例如,通过触发按钮获取或在页面加载等方式进行获取),则只应使用once()方法,然后可以如下链接两个调用:)

  var currency = 'EUR';
  var ref5 = db.ref().child('parentnode/currencies/value/' + currency + '_price');
  var ref6 = db.ref().child('parentnode/currencies/value/currency-source');

  ref5
    .once('value')
    .then(function(dataSnapshot) {
      console.log(dataSnapshot.val());
      return ref6.once('value');
    })
    .then(function(dataSnapshot) {
      console.log(dataSnapshot.val());
    });

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...