Firebase-admin won't write to database, gives no errors

允我心安 提交于 2019-12-06 11:22:11

问题


Firebase admin isn't writing to the database.

I am instantiating the database:

var db = admin.database();

Then setting up a reference to the table I want:

var systemsRef = db.ref("systems/");

I then have a function to check if the 'system', (an encrypted hardware id), exists.

function isSystemRegistered(id){
  var isTrue;
  systemsRef.once('value', function(snapshot) {
      isTrue = (snapshot.hasChild(id))? true : false;
  });
  return isTrue;
}

Which, as of yet returns false; which is true, because it doesn't exist yet. If the system doesn't exist, it writes the data.

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

I've experimented, and temporarily made my prototype database fully public for a few minutes, just to be sure my rules weren't the issue... They weren't: still no bueno. No writes to the database... and no errors.

I tried a different set, just be sure:

msystemsRef.set("I'm writing data", function(error) {
  if (error) {
    alert("Data could not be saved." + error);
  } else {
    alert("Data saved successfully.");
  }
});

Again, I'm using an admin account, with public rules, so I should see a now I'm writing data table, just below root. Nothing...

So I switched tactics and attempted to push to the database with the canned tutorial, with my database still fully public:

systemsRef.push({sysID : sys.info.name});

And nothing... Want am I missing?


回答1:


Make sure the credentials and databaseURL are correct.

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

Check if they're matching - credential from one app and databaseURL from another existing app could produce such result.

If you are not loading credential's data from file but from somewhere else, make sure it's not modified - I had an issue with newlines in private key when putting the credential's data to shell variable.




回答2:


In isSystemRegistered you're returning the synchronized value of isTrue which is undefined.

You should return the promise of the .once('value') method and in the calling method attach a then() to check if it exists.

You can also use the snapshot.exists() to check on a reference for existence.

Edit:

Suggested edit:

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

Running on Raspberry Pi raises some more questions.

  • How does it connect to the internet?
  • How fast is the connection?
  • What NodeJS version do you run?
  • Did this run successfully on your PC?



回答3:


Same issue here. I eventually realised that the database went offline before the command was even sent to firebase. This made sense because there was no error, since it never even sent the request.

Eg. .set({blah: 123}) does not immediately transmit to the server. Instead, something is placed on the node event queue to execute. If you let the database go offline too soon, it won't process the queue.

Perhaps (like me) you're calling admin.database().goOffline(); at the end of the script? If so, you may just need to defer or delay the offline method until after the transmission.

// (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);


来源:https://stackoverflow.com/questions/41646277/firebase-admin-wont-write-to-database-gives-no-errors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!