Firebase管理员不会写入数据库。
我正在实例化数据库:
var db = admin.database();
然后设置对我想要的表的引用:
var systemsRef = db.ref("systems/");
然后我有一个功能来检查'系统'(加密的硬件ID)是否存在。
function isSystemRegistered(id){
var isTrue;
systemsRef.once('value', function(snapshot) {
isTrue = (snapshot.hasChild(id))? true : false;
});
return isTrue;
}
其中,尚未返回false
;这是true
,因为它还没有存在。如果系统不存在,它会写入数据。
const sysID = getSysID();
var sys.info.name = generateUniqueSystemName();
if(isSystemRegistered(sysID){
console.log("system is already registered!");
} else {
msystemsRef.set({
sysID : sys.info.name
}, function(error){
console.log('There was an error while attempting to write to database: ' + error);
});
});
}
我已经进行了实验,暂时让我的原型数据库完全公开了几分钟,只是为了确保我的rules
不是问题......他们不是:仍然没有bueno。没有写入数据库...... 没有错误。
我尝试了不同的set
,请确保:
msystemsRef.set("I'm writing data", function(error) {
if (error) {
alert("Data could not be saved." + error);
} else {
alert("Data saved successfully.");
}
});
我再次使用管理员帐户,并使用public
规则,因此我应该在根目录下方看到一个现在的I'm writing data
表。没什么...
所以我切换了策略并尝试使用固定教程推送到数据库,我的数据库仍然完全公开:
systemsRef.push({sysID : sys.info.name});
没什么......我想失踪吗?
答案 0 :(得分:1)
在isSystemRegistered
中,您返回的isTrue
同步值为undefined
。
您应该返回.once('value')
方法的承诺,并在调用方法中附加then()
以检查它是否存在。
您还可以使用snapshot.exists()
检查存在的参考。
修改强>
建议编辑:
var systemRef = admin.database('system');
function isSystemRegistered(id) {
return systemRef.child(id).once('value')
.then(function (snap) {
return snap.exists();
});
}
function writeData(aSystem) {
var sysId = generateUniqueSystemName();
return systemRef.child(sysId)
.once('value')
.then(function (snapshot) {
if (!snapshot.exists()) {
return systemRef.child(sysId).update(aSystem);
}
// Here `sysId === snapshot.key`
return systemRef.child(sysId).set(aSystem);
})
.catch(function (err) {
console.error(err);
});
}
在Raspberry Pi上运行会引发更多问题。
答案 1 :(得分:1)
确保凭据和databaseURL正确无误。
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: databaseURL
});
检查它们是否匹配 - 来自一个应用的凭据和来自另一个现有应用的databaseURL可以产生这样的结果。
如果您没有从文件加载凭据的数据,但是从其他地方加载,请确保它没有被修改 - 在将凭证的数据放入shell变量时,我在私钥中出现了新问题。
答案 2 :(得分:0)
同一问题。我最终意识到,在命令甚至发送到Firebase之前,数据库已脱机。这是有道理的,因为没有错误,因为它甚至从未发送过请求。
例如。 .set({blah: 123})
不会立即传输到服务器。而是在node event queue上放置一些内容以执行。如果让数据库过早脱机,它将不会处理队列。
也许(像我一样)您正在脚本结尾处调用admin.database().goOffline();
?如果是这样,您可能只需要推迟或延迟离线方法,直到传输之后。
// (TYPESCRIPT)
import * as admin from 'firebase-admin';
let app = admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: "https://blahblah.firebaseio.com/",
});
admin.database().ref().push({ something: 123 }).then(() => {
console.log("push complete");
});
// delay before going offline
setTimeout(() => {
admin.database().goOffline();
process.abort();
}, 2000);