【问题标题】:Firebase-admin won't write to database, gives no errorsFirebase-admin 不会写入数据库,没有错误
【发布时间】:2017-01-14 02:40:48
【问题描述】:

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

什么都没有……我想我失踪了吗?

【问题讨论】:

  • 你解决了吗!?我也有同样的问题...
  • @FamicTech 不,我还没有解决它。这仍然是一个问题——我在一次会议上向谷歌提交了一个错误。但我们会看到 - 很难超越噪音。

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


【解决方案1】:

确保凭据和数据库 URL 正确。

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: databaseURL
});

检查它们是否匹配 - 来自一个应用的凭据和来自另一个现有应用的 databaseURL 可能会产生这样的结果。

如果您不是从文件中而是从其他地方加载凭据数据,请确保它没有被修改 - 在将凭据数据放入 shell 变量时,我遇到了私钥中的换行符问题。

【讨论】:

  • 您提出了一个很好的观点,我会仔细检查凭据和 URL。我认为它们是正确的,因为我在我的 MacBook 和 LinuxVM 上使用相同的凭据/URL 进行了测试,它在那里工作。但是我遇到的问题是在 Raspberry Pi 上使用相同的代码/包,但它不起作用。我意识到这是我没有提到的。我要投赞成票,因为这是关于主题且有效的,尽管我相当确定我在 3 个系统中的 2 个系统上使用了正确的凭据/URL。
【解决方案2】:

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 上成功运行?

【讨论】:

  • 我明天去看看,然后回复你,谢谢!
  • 我要投赞成票,因为你是对的,不过,我没有提到这个问题发生在 Raspberry Pi 上(而且只有那里),当我问这个问题时,我没有彻底证实这一事实原来的问题。我会更新我的问题。如果您愿意,请参阅我对另一个答案的评论以获取更多详细信息。
  • 您在树莓派上使用的是哪个 NodeJS 版本?
  • @NonCreature0714 我看到同样的问题也在树莓派上运行。你有没有发现这是否是直接原因?如果有怎么办?
【解决方案3】:

这里也是同样的问题。我最终意识到,甚至在命令发送到 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多