Test Firebase Authentication Cloud Functions Trigger on Local Machine With Emulators

November 17, 2020

Prerequisite

Setup Firebase Project with the following configuration

❯◯ Database: Deploy Firebase Realtime Database Rules
 ◉ Firestore: Deploy rules and create indexes for Firestore
 ◉ Functions: Configure and deploy Cloud Functions
 ◉ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules
 ◉ Emulators: Set up local emulators for Firebase features
 ◯ Remote Config: Get, deploy, and rollback configurations for Remote Config
=== Emulators Setup
? Which Firebase emulators do you want to set up? Press Space to select emulator
s, then Enter to confirm your choices. 
 ◉ Authentication Emulator
 ◉ Functions Emulator
 ◉ Firestore Emulator
 ◯ Database Emulator
 ◉ Hosting Emulator
❯◯ Pub/Sub Emulator

NOTE: Select the options which enable Web UI for emulators as well

Cloud Functions

Edit functions/initUser.js

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

const db = admin.firestore();

// https://firebase.google.com/docs/functions/auth-events
exports.initUser = functions.auth.user().onCreate(async (user) => {

  let docRef = db.collection('user').doc(user.uid);

  const batch = db.batch();

  /*
  await docRef.set({
    created: admin.firestore.Timestamp.now(),
    name: user.displayName,
    active: false
  });
   */

  batch.set(docRef, {
    created: admin.firestore.Timestamp.now(),
    name: user.displayName,
    active: false
  });

  docRef = db.collection('user_private').doc(user.uid);

  batch.set(docRef, {
    email: user.email,
  });

  await batch.commit();
});

Edit functions/index.js

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

/*
exports.hello = functions.https.onRequest((req, res) => {
  res.send("Hello!");
});
 */

const initUser = require('./initUser');

exports.initUser = initUser.initUser

NOTE: From Firebase Cloud Function (Node.js) Write to Firestore Upon Firebase Authentication User Signup

Test on Local Machine with Emulators

Start Emulators

firebase emulators:start
i  emulators: Starting emulators: auth, functions, firestore, hosting
⚠  functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: database, pubsub
✔  functions: Using node@10 from host.
⚠  functions: Your GOOGLE_APPLICATION_CREDENTIALS environment variable points to /code/firebase/algot/secret/app-engine.json. Non-emulated services will access production using these credentials. Be careful!
⚠  firestore: Did not find a Cloud Firestore rules file specified in a firebase.json config file.
⚠  firestore: The emulator will default to allowing all reads and writes. Learn more about this option: https://firebase.google.com/docs/emulator-suite/install_and_configure#security_rules_configuration.
i  firestore: Firestore Emulator logging to firestore-debug.log
i  hosting: Serving hosting files from: public
✔  hosting: Local server: http://localhost:5000
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "/code/firebase/algot/functions" for Cloud Functions...
✔  functions[initUser]: auth function initialized.

┌────────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! View status and logs at localhost:4000 │
└────────────────────────────────────────────────────────────────┘

┌────────────────┬────────────────┬──────────────────────────┐
│ Emulator       │ Host:Port      │ View in Emulator UI      │
├────────────────┼────────────────┼──────────────────────────┤
│ Authentication │ localhost:9099 │ localhost:4000/auth      │
├────────────────┼────────────────┼──────────────────────────┤
│ Functions      │ localhost:5001 │ localhost:4000/functions │
├────────────────┼────────────────┼──────────────────────────┤
│ Firestore      │ localhost:8080 │ localhost:4000/firestore │
├────────────────┼────────────────┼──────────────────────────┤
│ Hosting        │ localhost:5000 │ n/a                      │
└────────────────┴────────────────┴──────────────────────────┘
  Other reserved ports: 4400, 4500

You might bump into Firestore emulator error if you didn’t have Java installed. Run sudo apt-get install openjdk-8-jre to install java.

⚠  firestore: Fatal error occurred: 
   Firestore Emulator has exited because java is not installed, you can install it from https://openjdk.java.net/install/, 
   stopping all running emulators

Look for functions[initUser]: auth function initialized to ensure there is no syntax error with our cloud functions.

Open localhost:4000/auth in brower and click Add User to simulate user signup via Firebase Authentication.

Firebase Auth Emulator

  • Fill in Display name, Email and Password
  • Click Save

Click on Firestore tab or http://localhost:4000/firestore and you should see the new entry created by your cloud functions

Firestore Emulator

Click on Logs or http://localhost:4000/logs and you should see the log of the cloud function execution.

16:46:06 I function[initUser] Beginning execution of "initUser"
16:46:06 I function[initUser] Finished "initUser" in ~1s

References:

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.