How can I mock the `Reference.prototype.update` method in `firebase-admin/database` with Jest? - firebase

I'm trying to spy on the update method of Firebase Realtime Database using firebase-admin
My code roughly looks like:
import admin = require("firebase-admin");
import * as database from "firebase-admin/database";
admin.initializeApp();
const db = database.getDatabase();
...
function X() {
const myRef = db.ref("hello");
...
myRef.update(updates);
}
I'd like to spy on these myRef.update calls with Jest.
As firebase-admin is not modular, I can not simply rewrite the final call to update(myRef, updates).
I could not find any exports of the database.Reference class, only the interface. How can I still have something like jest.spyOn(database.Reference.prototype, "update")?

Related

Blocking auth triggers in cloud functions for firebase second generation

I am referring this https://firebase.google.com/docs/functions/beta/auth-blocking-events documentation to implement Blocking auth triggers using 2nd generation cloud function for firebase,
I have created and deployed functions but the problem is that, while registering the triggers under the Blocking functions tab in the Firebase Authentication console, It does not shows that deployed triggers (beforeUserSignedIn, beforeUserCreated) for registering.
Below is my code,
import functions from 'firebase-functions/v2'
import admin from 'firebase-admin'
import { beforeUserCreated, beforeUserSignedIn } from 'firebase-functions/v2/identity'
import serviceKey from './serviceKey.json' assert {type: 'json'}
admin.initializeApp(serviceKey)
export const beforecreated = beforeUserCreated((event) => {
console.log("EVENT DATA FOR AUTH beforecreated....", event.data)
return;
});
export const beforesignedin = beforeUserSignedIn((event) => {
console.log("EVENT DATA FOR AUTH beforesignedin....",event.data)
});
I have tried Blocking auth triggers for first-generation cloud functions for firebase and it's working fine, and also I can register that blocking auth triggers. But this is not working for the second generation cloud function for firebase.

How to get the current https functions endpoint for firebase when using/not using emulator

I have a graphql api running on a firebase function and I develop locally for the most part.
Before when I called the firebase functions directly I would use the connectFunctionsEmulator function to conditionally connect to my local emulator and when I called the functions using getFunctions it would know to call my localhost endpoint.
However I'm trying to use Apollo client and I'm not sure how to determine when the local emulators have been connected and when they have not as well as how to determine the absolute url when calling the function like the way firebase does when I call it using the firebase functions helpers.
I went snooping through the code and when I call the connectFunctionsEmulator function it updates a variable called functionsInstance.emulatorOrigin.
This is not present in the functions typing but I'm still able to access the value by doing getFunctions().emulatorOrigin.
If the value is not set to null that means firebase will be talking to my emulators and not to the live endpoint.
function getGraphQLUri(): string {
const functions = getFunctions();
const app = getApp();
const { projectId } = app.options;
const { region } = functions;
// emulatorOrigin is not defined in the typings but it exists
// #ts-ignore
const emulator = functions.emulatorOrigin;
let url: string = "";
if (emulator) {
url = `${emulator}/${projectId}/${region}/graphql`;
} else {
url = `https://${region}-${projectId}.cloudfunctions.net/graphql`;
}
return url;
}
I would appreciate if someone at Google can confirm whether this approach might continue to be supported in the future.

Why Do I Keep Getting This CORS Error With Firebase

I keep getting this same CORS error when trying to perform basic requests with the Firebase real-time database.
Ive followed 2 separate tutorials on how to request/post data to/from the Firebase real-time database and every time I reload the page it comes up saying:
Access to script at 'https://console.firebase.google.com/project/ProjectName*******/database/data/' (redirected from 'https://***ProjectName*****-default-rtdb.firebaseio.com/') from origin 'http://localhost:5005' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I have googled this and have tried many solutions, some from this site and nothing has helped.
Ive installed GSUTIL and tried to modify the CORS rules through that...
Eg. Running gsutil cors set cors.json gs://your-bucket Through GSUTIL
It just returns 'No file in directory'
I then tried putting a cors.json file in my firestore and it still doesn't help
Im just at a loss and have no idea what to do now
I am just getting started with coding and know nothing about CORS
So please take note of that...
Any help would be greatly appreciated
When importing getDatabase to use the Firebase RTDB, you don't want to use either of these:
import { getDatabase, ... } from "https://[PROJECT_ID]-default-rtdb.firebaseio.com/"
const { getDatabase, ... } = await import("https://[PROJECT_ID]-default-rtdb.firebaseio.com/")
This is because neither of these are importing the Firebase Web SDK.
To import the Firebase Web SDK for the RTDB in a build environment, you would use either of these:
import { getDatabase, ... } from "firebase/database"
const { getDatabase, ... } = await import("firebase/database");
To import the Firebase Web SDK for the RTDB in a browser, you would use either of these:
import { getDatabase, ... } from "https://www.gstatic.com/firebasejs/9.1.3/firebase-database.js"
const { getDatabase, ... } = await import("https://www.gstatic.com/firebasejs/9.1.3/firebase-database.js");
The URL of your database normally goes into the Firebase configuration object you pass to initializeApp like so:
const firebaseConfig = {
apiKey: "apiKey",
authDomain: "projectId.firebaseapp.com",
databaseURL: "https://databaseName.firebaseio.com", // <-- here
storageBucket: "bucket.appspot.com"
};
const app = initializeApp(firebaseConfig);
Then when you need to use it, you just call either of these as needed:
// uses default app & default database
const database = getDatabase();
// uses given app & default database
const database = getDatabase(app);
When you are using more than one RTDB instance (shared from another project, different region, etc), you pass in the URL of that instance as the second argument like so:
// uses default app & given database
const secondDatabase = getDatabase(getApp(), "https://secondDatabaseName.firebaseio.com");
// uses given app & given database
const secondDatabase = getDatabase(app, "https://secondDatabaseName.firebaseio.com");

Use a Firestore Database in Dialogflow project

I want to integrate my Firestore using data I got in my Dialogflow project.
I was searching in the net and I found just some random things.
I wrote some console.log inside, because I want to understand how does it work, but nothing seems happening, and I don't even know where I can find my logs.
Here it is my index.js Dialogflow code:
'use strict';
// Import the Dialogflow module from the Actions on Google client library.
//const {dialogflow} = require('actions-on-google');
const {dialogflow,Permission,SimpleResponse,Image,Carousel,BrowseCarousel,BasicCard,Button,BrowseCarouselItem,Suggestions,List,MediaObject} = require('actions-on-google');
// Import the firebase-functions package for deployment.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
// Instantiate the Dialogflow client.
const app = dialogflow({debug: true});
admin.initializeApp(functions.config().firebase);
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
console.log('Request headers: ');
});
Is there something I am missing?
Sorry, but it's my first time using Dialogflow.
Since you're using the built-in editor, your logs will be in the Firebase Cloud Functions logs section. To get there
Go to https://console.firebase.google.com/ and select your project.
Select "Functions" on the left navigation.
Select "Logs" in the navigation towards the top.

Cloud Functions for Firebase - Getting permission denied even with admin initialized

I setup my cloud functions with firebase-admin like :
const admin = require('firebase-admin');
const fn = require('firebase-functions');
admin.initializeApp(fn.config().firebase);
However I am getting permission denied upon writing on the database. What's weird is it only happens to some collection but not to all of them. Some works, some won't.
My understanding of admin.initializeApp(fn.config().firebase); is that this will allow my cloud functions to have an absolute power over the database regardless of the security rules.
Here's the error:
EDIT
I write the data like this.
exports.foo = fn.database.ref('some-path').onWrite(e => {
// some handling
const ref = e.data.ref;
return ref.child('bar').set('some-data').then( // ).catch( // );
})
To obtain full access to the database from the DeltaSnapshot provided in an event, use adminRef:
Returns a Reference to the Database location where the triggering
write occurred. Similar to ref, but with full read and write access
instead of end-user access
exports.foo = fn.database.ref('some-path').onWrite(e => {
// some handling
const ref = e.data.adminRef; // <== CHANGED
return ref.child('bar').set('some-data').then( // ).catch( // );
})

Resources