0

I am looking to anonymously connect to a Firestore and grab some data from a collection. This works perfectly fine under javascript, while it fails ("FirebaseError: Missing or insufficient permissions") under node.js. Any pointers will be appreciated.

This is the code that works without a hitch under javascript (I have omited the 'script' includes) and it returns data as expected:

var config = {
  apiKey: "xxx",
  authDomain: "xxx.firebaseio.com",
  projectId: "xxx",
  storageBucket: "xxx.appspot.com",
};
firebase.initializeApp(config);

firebase.auth().signInAnonymously().catch(function(error) {
  var errorCode = error.code;
  var errorMessage = error.message;
  console.log(error.message);
});

foo();
async function foo() {
  var db=firebase.firestore();
  var query = await db.collection("collection").limit(5).get();
  query.forEach(function(doc) {
    console.log(doc.data());
  });
}

This is the code that does not work under node.js. The config/authdata is exactly the same as in the js example above. (It uses the firebase (client) library. My understanding is that the firebase-admin library does not allow anonymous signin.)

const firebase=require('firebase');

  var config = {
  apiKey: "xxx",
  authDomain: "xxx.firebaseio.com",
  projectId: "xxx",
  storageBucket: "xxx.appspot.com",
  };

firebase.initializeApp(config);

firebase.auth().signInAnonymously().catch(function(error) {
    var errorCode = error.code;
    var errorMessage = error.message;
    console.log(error.message);
  });

let db = firebase.firestore();

db.collection('collection').get()
  .then((snapshot) => {
    snapshot.forEach((doc) => {
      console.log(doc.id, '=>', doc.data());
    });
  })
  .catch((err) => {
    console.log('Error getting documents', err);
  });

The following error is triggered when db.collection('collection').get() is called. (earlier anonymous signing goes through)

Error getting documents { FirebaseError: Missing or insufficient permissions.
    at new FirestoreError (/root/node_modules/@firebase/firestore/dist/index.node.cjs.js:1201:28)
    at JsonProtoSerializer.fromRpcStatus (/root/node_modules/@firebase/firestore/dist/index.node.cjs.js:19708:16)
    at JsonProtoSerializer.fromWatchChange (/root/node_modules/@firebase/firestore/dist/index.node.cjs.js:19955:44)
    at PersistentListenStream.onMessage (/root/node_modules/@firebase/firestore/dist/index.node.cjs.js:16828:43)
    at /root/node_modules/@firebase/firestore/dist/index.node.cjs.js:16757:30
    at /root/node_modules/@firebase/firestore/dist/index.node.cjs.js:16797:28
    at /root/node_modules/@firebase/firestore/dist/index.node.cjs.js:17844:20
    at process._tickCallback (internal/process/next_tick.js:68:7)
  code: 'permission-denied',
  name: 'FirebaseError',
  toString: [Function] }

Thanks again for any pointers!

3
  • Security rules are rejecting the query. Commented May 7, 2020 at 5:06
  • Can you post screenshot of your Firestore rules? Commented May 7, 2020 at 5:06
  • Unfortunately, I don't have the rules for this one, as I am working with a 3rd party firebase account. Whatever the rules are, they should apply to both versions of the library in the same way. Why the inconsistency? There appears to be a fundamental difference in the way the library works on JS and Node. Commented May 7, 2020 at 5:24

1 Answer 1

1

One possibility is that you are actually not signed-in when you fetch Firestore. As a matter of fact the signInAnonymously() method is asynchronous and you don't wait that the Promise returned by this method resolves before fetching Firestore.

So, the following may solve your problem:

firebase.initializeApp(config);
let db = firebase.firestore();

firebase.auth().signInAnonymously()
.then(cred => {
    return db.collection('collection').get()
})
.then((snapshot) => {
    snapshot.forEach((doc) => {
      console.log(doc.id, '=>', doc.data());
    });
})
.catch((err) => {
    console.log(err);
});

Note that you should do the same in the JavaScript SDK version:

firebase.auth().signInAnonymously()
.then(cred => {
  foo();
}}
.catch(function(error) {
  var errorCode = error.code;
  var errorMessage = error.message;
  console.log(error.message);
});
Sign up to request clarification or add additional context in comments.

2 Comments

Very interesting point. It could be that internally js and node handle some asynchronous calls differently and you only get a promis in node, while js returns an object. Let me check and come back in a bit.
Thanks Renaud. So it wasn't a firebase library issue, just specific to the way node async stuff works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.