Setup Firebase Hosting and Functions (Node)
You want to install Firestore Emulator as well
firebase init ######## #### ######## ######## ######## ### ###### ######## ## ## ## ## ## ## ## ## ## ## ## ###### ## ######## ###### ######## ######### ###### ###### ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ######## ######## ## ## ###### ########You're about to initialize a Firebase project in this directory: /code/firebase/journeyBefore we get started, keep in mind: * You are currently outside your home directory * You are initializing in an existing Firebase project directory? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. Emulators: Set up local emulators for Firebase features=== Project SetupFirst, let's associate this project directory with a Firebase project.You can create multiple project aliases by running firebase use --add,but for now we'll just set up a default project.i .firebaserc already has a default project, using journeyx.=== Emulators Setup? Which Firebase emulators do you want to set up? Press Space to select emulators, then Enter to confirm your choices. Functions, Firestore, Hostingi Port for functions already configured: 5001? Which port do you want to use for the firestore emulator? 8080i Port for hosting already configured: 5000? Would you like to download the emulators now? Yesi firestore: downloading cloud-firestore-emulator-v1.11.2.jar...Progress: ======================================================> (100% of 90MB)i Writing configuration info to firebase.json...i Writing project information to .firebaserc...✔ Firebase initialization complete!
Start Firestore Emulator
firebase emulators:start --only firestore,functions
NOTE: firebase serve --only functions,firestore
used to be supported, but now it shows Error: Please use firebase emulators:start to start the Realtime Database or Cloud Firestore emulators. firebase serve only supports Hosting and Cloud Functions.
NOTE: I tried running firebase emulators:start --only firestore
followed by firebase serve
, it complained of The Cloud Firestore emulator is not running, so calls to Firestore will affect production
. Despite the warning, the testing seems to work, though I am not aware of any side effects.
Install Packages
npm install firebase-admin --savenpm istall @firebase/testing --save-dev
Create cloud functions to access Firestore Emulator.
Edit functions/index.js
.
Option 1: using @firebase/testing
const isDev = process.env.FUNCTIONS_EMULATORconst functions = require('firebase-functions');let admin // serverlet firebase // testinglet firestorelet dbconst projectId = 'PROJECT_NAME'if (isDev) { firebase = require("@firebase/testing") db = firebase.initializeTestApp({ projectId: projectId }).firestore() firestore = firebase.firestore // admin = firebase}else { admin = require('firebase-admin') admin.initializeApp(functions.config().firebase) db = admin.firestore() firestore = admin.firestore // firebase = admin}// exports.requestInvite = functions.https.onRequest(async (req, res) => {exports.requestInvite = functions.https.onCall(async (data, context) => { const email = data.email // use email as docId const docId = Buffer.from(email).toString('base64') const docRef = db.collection('request_invite').doc(docId) if (isDev) { // optional - delete database await firebase.clearFirestoreData({ projectId }) } const doc = await docRef.get() if (doc.exists) { console.log('doc exist', doc.data()) } await docRef.set({ created: firestore.Timestamp.now(), email: email }) return { text: `Hello ${email}!`, docId: docRef.id }})
NOTE: Refer to onRequest vs onCall.
NOTE: Bear in mind @firebase/testing
is a client side package, so data type such as firestore.Timestamp
cannot be mixed with firebase-admin
which is a server package.
Option 2: firebase-admin only
const functions = require('firebase-functions');const admin = require('firebase-admin')admin.initializeApp(functions.config().firebase)const db = admin.firestore()const firestore = admin.firestoreexports.requestInvite = functions.https.onCall(async (data, context) => { const email = data.email // use email as docId const docId = Buffer.from(email).toString('base64') const docRef = db.collection('request_invite').doc(docId) const doc = await docRef.get() if (doc.exists) { console.log('doc exist', doc.data()) } await docRef.set({ created: created: firestore.Timestamp.now(), email: email }) return { text: `Hello ${email}!`, docId: docRef.id }})
If you have Cloud Functions that use the Firebase Admin SDK to write to Cloud Firestore, these writes will be sent to the Cloud Firestore emulator if it is running. If further Cloud Functions are triggered by those writes, they will be run in the Cloud Functions emulator. - Source
NOTE: Once emulator is stopped, all data are automatically cleared.
References: