Firebase-admin无法写入数据库,不会出现错误

时间:2017-01-14 02:40:49

标签: javascript node.js firebase firebase-realtime-database firebase-admin

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});

没什么......我想失踪吗?

3 个答案:

答案 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上运行会引发更多问题。

  • 它如何连接到互联网?
  • 连接速度有多快?
  • 您运行的是什么NodeJS版本?
  • 这是否在您的PC上成功运行?

答案 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);