我现在已经花了 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_ 发生变化(通过修改现有值或添加新评级)时,更新与 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_ ...”行和后续控制台日志中所尝试的那样。
我已经通读了文档 ( https://firebase.google.com/docs/functions/database-events ) 和 stackexchange 帖子无数次,但我要么得到
“类型错误: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 关键字与 Once('value).then(snapshot => snapshot.val()) 结合使用来获取值,但这不会编译,或者如果我删除 async/await,则 promise 永远不会兑现。
最佳答案
从数据库检索值是异步的。
如果你看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
的 Promise,并且 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,所有这些下划线都非常丑陋,只是说,尝试驼峰命名法;)如果它们已经是字符串,或者您正在连接,则不需要将变量包装在 String()
中与其他字符串。对于不改变的变量,您可以使用 const
而不是 let
。
关于javascript - 从 firebase 函数读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47903621/