How do I increment a value for an existing object in Firebase?

核能气质少年 提交于 2019-12-25 00:57:18

问题


I'm building a step counter app. I got an iOS app that pushes the sum of each day to /users/{mobile}/steps/{date}/ When a new steps child is updated or added, I want to sum the value of all the steps for that particular user and update his stepsTotal.

To achieve that I need to

  1. Find the original user and sum all the steps.
  2. Save the new value to stepsTotal.

I would be most grateful if someone could give some help here. :-)

database

{

  "users": {
    "92291000": {
      "firstName": "Tore",
      "stepsTotal": "1500",
      "steps": {
        "02-09-2017": "500",
        "03-09-2017": "1000"
      },

import.js

var db       = admin.database();
var dbRoot   = db.ref("/");
var usersRef = dbRoot.child("users");

// This works    
function saveUser(attributes) {
  let mobile =  attributes.mobile;
  delete attributes['mobile']
  let user = usersRef.child(mobile);
  user.update(attributes);
}


function increaseSteps( { mobile=null, steps=null } = {}) {
  // Find the User
  console.log("looking for mobile", mobile);  // OK
  let userRef = usersRef.child(mobile);

  // Here I'm not able to read the old data from the user.
  userRef.transaction(function(user) {
    console.log("user: ", user);  // null
    // ^ User is null. 
  });


/*  
  If I mangage to find user above, I expect to do something like this. 
  Or it is possible to only update *stepsTotal*?
*/

  let attributes = {
    firstName: user.firstName,
    lastName: user.lastName,
    stepsTotal: user.stepsTotal + steps,
  }
  user.update( attributes );
}

回答1:


If I understand correctly, you have a problem in this snippet of the code:

let userRef = usersRef.child(mobile);

// Here I'm not able to read the old data from the user.
userRef.transaction(function(user) {
  console.log("user: ", user);  // null
  // ^ User is null. 
});

In Firebase Database transactions the initial value is often null. From the Firebase documentation on transactions:

Transaction Function is Called Multiple Times

Your transaction handler is called multiple times and must be able to handle null data. Even if there is existing data in your database it may not be locally cached when the transaction function is run.

This is due to how Firebase transactions work behind the scenes. To learn more about that, see my answers here Transcation updateFunction parameter is null and Firebase runTransaction not working.

The solution is to handle both cases: if the user node doesn't exist yet count the initial number of steps, otherwise update the number of steps:

let userRef = usersRef.child(mobile);

userRef.transaction(function(user) {
  return (user || 0) + new_steps_for_user;
});


来源:https://stackoverflow.com/questions/45714367/how-do-i-increment-a-value-for-an-existing-object-in-firebase

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!