Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using firebase-admin. What are service account credentials used for?

I'm building a cloud function to get some documents and generate an HTML response.

And right now what I have is:

myFunction.js

import * as admin from 'firebase-admin';
import serviceAccount from './someServiceAccountKey.json';

// OPTION #1  <-----

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://myfirebaseproject.firebaseio.com"
});

// OPTION #2 <------

admin.initializeApp();

// FUNCTION <------

async function(req,res) {

  const docSnapshot = await admin.firestore().collection('someCollection').doc('someDoc').get();
  // AND SO ON...
}

At some point I've created that serviceAccount key (I don't remember from which tutorial) and I've been using on my functions to "grant access" to the firebase-admin (as in OPTION #1 from the code above). Because I thought I needed to.

But I've found out that even without any initializing parameter or serviceAccount credential (as in OPTION #2 from the code above), I can initialize the firebase-admin and access my firebase project resources (like Firestore) without any issues.

And I can do this on deployed functions, which makes sense, since they are inside the Firebase project's cloud environment, and if they were deployed, they should have access to the project's resources, without the need for a service account, right?

But I also found out that I can do this in my Node.js local environment. By calling the function with npx babel-node myFunction.js (using babel node to transpile and execute). The function is able to access and query my Firestore (on-line data, this is not the Firestore emulator) without any issues.

Where is my local environment getting permission to access my project's resources from? Is it from the firebase-tools that is installed and logged in my project?

If I don't need them in both cases. What are service accounts mainly used for?

like image 464
cbdeveloper Avatar asked Nov 21 '19 12:11

cbdeveloper


2 Answers

You initialize SDK in different way depending on the environment:

Cloud Functions

const admin = require('firebase-admin');
const functions = require('firebase-functions');

admin.initializeApp(functions.config().firebase);

let db = admin.firestore();

Google Cloud Platform

const admin = require('firebase-admin');

admin.initializeApp({
  credential: admin.credential.applicationDefault()
});

const db = admin.firestore();
// ...

Node server

const admin = require('firebase-admin');

let serviceAccount = require('path/to/serviceAccountKey.json');

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

let db = admin.firestore();

Look here for more details

So, your observations are correct. However, since even using OPTION #2 you are getting access to your firebase, then most likely you need to check your database rules and make sure you are prohibiting unauthenticated access to your db.

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

More about the rules here.

like image 166
matcheek Avatar answered Oct 22 '22 04:10

matcheek


Firebase data is secured using rules, before you set up any rules, any user (even unauthenticated) can access your data.

https://firebase.google.com/docs/rules/basics

Once you have rules set up, then either the user or the server will have to authenticate in order to read/write data.

Users authenticate by logging on with google (or whatever client side security you have ocnfigured).

Servers authenticate by using the service account. Service accounts default to having admin access to the database.

https://firebase.google.com/docs/database/admin/start#authenticate-with-admin-privileges

like image 43
paul Avatar answered Oct 22 '22 03:10

paul