从firebase函数读取数据

时间:2017-12-20 10:16:28

标签: javascript android firebase google-cloud-functions

我现在花了16个小时的时间用javascript撕掉我的头发,所以我觉得是时候问别人了。

我有一个在android studio中制作的Android应用程序,它连接到一个看起来大致如下的firebase数据库:

nameOfDatabase
    Places
        Bar
            B001
                place_ID_ : "B001"
                ...
                average_rating_ : 0
                ...
                number_of_ratings_ : 0

            ...other bars

        ...other place types  

    Ratings
        ratingID1
            place_ID_ : "B001"
            rating_ : 3
            user_ID_ : 4315732985097

            ...other parameters

        ...other ratings

我想要做的只是更新rating_ID_的匹配place_ID_的地方的number_of_ratings_和average_ratings_,无论是通过修改现有值还是添加新评级。我的firebase函数节点模块的index.js代码如下所示:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.UpdateAverageRatings = functions.database.ref('/Ratings/{rating_uid}/rating_').onWrite(event => {

    let place_ID_ = admin.database().ref('Ratings/' + String(event.params.rating_uid) + '/place_ID_').val();

    console.log(place_ID_);

    let place_type_ = 'BARs';
    let place_ID_ = 'B001';
    let avg_rating_ = 0;
    let accumulated_rating_ = 0;
    let number_of_ratings_ = 0;

    //Object.keys(place_ID_.parent).forEach(function(key) {
    //    if (place_ID_.parent[key] == 'place_ID_'){
    //        accumulated_rating_ += place_ID_.parent[key].value();
    //        number_of_ratings_ += 1;
    //}});

    let place_change_ = admin.database().ref('Places/' + String(place_type_) + '/' +String(place_ID_));

    place_change_.child('average_rating_').set(avg_rating_);
    place_change_.child('number_of_ratings_').set(number_of_ratings_);

    return 0;

  });

在返回之前的最后两行中设置值可以正常工作,但是现在我只是将虚拟值设置为“0”。注释掉了分配正确值的想法供以后使用。

问题在于,无论我尝试什么,我似乎都无法读取数据库中的任何值,如'let place_ID_ ...'行和随后的控制台日志所示。 < / p>

我已经无数次阅读了文档(https://firebase.google.com/docs/functions/database-events)和stackexchange帖子,但我得到了

“TypeError:admin.database(...)。ref(...)。val不是函数”

在firebase控制台日志中,或者如果我删除val();

W {
  u: 
   dh {
     app: 
      FirebaseApp {
        firebaseInternals_: [Object],
        services_: [Object],
        isDeleted_: false,
        name_: '[DEFAULT]',
        options_: [Object],
        database: [Function: bound ],
        INTERNAL: [Object] },
     L: 
      Tb {
        host: 'projectname.firebaseio.com',
        domain: 'firebaseio.com',
        Pc: true,
        ne: 'projectname',
        tg: false,
        ef: '',
        Za: 'projectname.firebaseio.com' },
     Ua: Ff { qc: {} },
     Sc: null,
     ca: he { tb: [] },
     td: 1,
     Qa: 
      kh {
        id: 0,
        f: [Function],
        nd: {},
        '$': {},
        pa: [],
        Lc: 0,
        Hc: [],
        ma: false,
        Ra: 1000,
        qd: 300000,
        Eb: [Function: bound ],
        Gc: [Function: bound ],
        se: [Function: bound ],
        L: [Object],
        xe: null,
        Ab: null,
        Ea: null,
        mb: null,
        Xc: [Object],
        ae: false,
        he: 0,
        Rd: undefined,
        sb: [Object],
        Kb: true,
        Ed: {},
        kg: 0,
        Oe: true,
        je: null,
        xc: null },
     va: 
      kh {
        id: 0,
        f: [Function],
        nd: {},
        '$': {},
        pa: [],
        Lc: 0,
        Hc: [],
        ma: false,
        Ra: 1000,
        qd: 300000,
        Eb: [Function: bound ],
        Gc: [Function: bound ],
        se: [Function: bound ],
        L: [Object],
        xe: null,
        Ab: null,
        Ea: null,
        mb: null,
        Xc: [Object],
        ae: false,
        he: 0,
        Rd: undefined,
        sb: [Object],
        Kb: true,
        Ed: {},
        kg: 0,
        Oe: true,
        je: null,
        xc: null },
     qg: Df { qf: {}, Sc: [Object], va: [Object] },
     jc: Vc { sd: '', Mc: null, A: [Object] },
     fe: Nb { Hd: [Object] },
     md: Dg { wa: [Object], hb: [Object], Be: {}, fc: {}, zc: [Object] },
     ia: Eb { B: null, k: null },
     Xa: ch { ta: [Circular], ba: [Object], INTERNAL: [Object] },
     cd: 0,
     ge: null,
     K: Dg { wa: [Object], hb: [Object], Be: {}, fc: {}, zc: [Object] } },
  path: G { o: [ 'Ratings', 'ratingID1', 'place_ID_' ], Y: 0 },
  m: 
   jf {
     xa: false,
     ka: false,
     Ib: false,
     na: false,
     Pb: false,
     oa: 0,
     kb: '',
     bc: null,
     xb: '',
     Zb: null,
     vb: '',
     g: Ae {} },
  Kc: false,
  then: undefined,
  catch: undefined }

,鉴于此数据库键仅包含整数值,这是相当不可思议的。

非常感谢任何帮助,如有必要,我可以提供更多信息。

修改 我现在尝试使用async / await关键字加上一次('value).then(snapshot =&gt; snapshot.val())来获取值,但这不会编译,或者如果我删除async / await,承诺永远不会解决。

1 个答案:

答案 0 :(得分:2)

从数据库中检索值是异步。

如果查看https://firebase.google.com/docs/database/web/read-and-write,它会有一次检索值的示例:

var userId = firebase.auth().currentUser.uid;
return firebase.database().ref('/users/' + userId).once('value').then(function(snapshot) {
  var username = (snapshot.val() && snapshot.val().username) || 'Anonymous';
  // ...
});

您可以使用on('value')来接收值的更新,也可以使用once('value')获取一次。两者都返回通过snapshot的承诺,而snapshot.val()将为您提供该节点的值。

因此您可以像这样检索值:

const place_ID_ = await admin.database().ref(`Ratings/${event.params.rating_uid}/place_ID_`).once('value').then(snapshot => snapshot.val());
console.log('place_ID_:', place_ID_);

Psst,所有那些下划线都非常丑陋,只是说,尝试camelCase;)如果它们已经是字符串,或者你正在与其他字符串连接,则不需要在String()中包装变量。您可以将const用于不更改的变量,而不是let