2

I want to set up a test suit to write a unit test for my Firebase application which connects to the Firestore emulator that is running locally on port 8080

Here is my firebase configuration in index.js

    const functions = require("firebase-functions");
    const dotenv = require('dotenv');
    dotenv.config();

    const emailFormatter = require("./emailFormatter");

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

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

And the following is my functions.test.js

    const admin = require('firebase-admin');
    const serviceAccount = require('../../../fir-react-mailer-firebase-adminsdk-wfei1-0fff68d44e.json');

    const testConfig = {
       credential: admin.credential.cert(serviceAccount),
       databaseURL: 'http://localhost:8080'
    }

    const testApp = admin.initializeApp(testConfig, 'test');

    const projectConfig = {
       projectId: 'fir-react-mailer',
       databaseURL: 'http://localhost:8080',
    }

    const testF = require('firebase-functions-test')(projectConfig, serviceAccount);

    const myFinctions = require('../index')

    let db = admin.firestore(testApp)

Here is my package.json

    {
      "name": "functions",
      "description": "Cloud Functions for Firebase",
      "scripts": {
        "serve": "firebase emulators:start --only functions",
        "shell": "firebase functions:shell",
        "start": "npm run shell",
        "deploy": "firebase deploy --only functions",
        "logs": "firebase functions:log",
        "test": "jest"
      },
      "engines": {
        "node": "12"
      },
      "dependencies": {
        "chalk": "^4.1.0",
        "dotenv": "^8.2.0",
        "firebase-admin": "^8.9.0",
        "firebase-functions": "^3.3.0",
        "nodemailer": "^6.4.6"
      },
      "devDependencies": {
        "@types/jest": "^26.0.20",
        "firebase-functions-test": "^0.1.7",
        "jest": "^26.6.3"
      },
      "private": true
    }

When running the command npm run test, I am getting the following error on the console.

enter image description here

Please suggest to me, If I am doing something wrong. I am a newbie to Firebase, so this whole setup is confusing.

Andrew
  • 795
  • 4
  • 18
  • I'm not entirely sure if this will help but it looks like it's trying to read the credentials file? Have you tried creating one or making sure it exists locally? There's some more people working a similar issue here: https://stackoverflow.com/questions/54711038/firebase-cloud-functions-failed-to-read-credentials-from-file – Ebsan Mar 16 '21 at 16:42

2 Answers2

0

I was having this issue as well and it was because I had to provide the location of the serviceAccount json file in relation to the functions folder. I also didn't import it and instead provided the string. So if my project is like so:

functions
 |
 +-- src
 |    
 +-- test
 |  |  
 |  \-- functions.test.js
 |    
 +-- package.json
 +-- service-account.json

I would change your functions-test variable to:

const testF = require('firebase-functions-test')(projectConfig, "./service-account.json");

You might also try calling initializeApp only once. It looks like you're calling initializeApp() twice. The first one is in your test code at line 9 and then again in your actual code. The one from the test code looks right, but then your actual code is calling it again without the testConfig.

Maybe try wrapping admin.initializeApp() in an if statement so it doesn't get initialized unless it has to (which will occur in production).

if (admin.apps.length === 0) {
  admin.initializeApp();
}
Ebsan
  • 758
  • 1
  • 10
  • 33
0

As per the documentation:

After creating your service account, you need to download the service account key to your machine(s) where your application runs. You can either use the GOOGLE_APPLICATION_CREDENTIALS environment variable or write code to pass the service account key to the client library.

You need to set the Windows environment variables like this:

With PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\my-key.json"

For example:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\my-key.json"

With command prompt:

set GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\my-key.json"

Try to avoid hard coding the location of your credentials file if you can to reduce the amount of code you write and it means your code is reusable.

Andrew
  • 795
  • 4
  • 18