test my firebase auth triggers locally - firebase

I would like to test some firebase database and auth triggers locally and have found this documentation https://firebase.google.com/docs/functions/local-emulator#invoke_realtime_database_functions.
Following along the instructions I typed
firebase functions:shell
and then invoked my custom firebase trigger with
createNewUser({user: {email: 'some#email.com'}},{auth: {uid: '123'}})
However, this gives me the error
firebase > createNewUser({user: {email: 'some#email.com'}},{auth: {uid: '123'}})
'Successfully invoked function.'
firebase > info: User function triggered, starting execution
info: Function crashed
TypeError: Cannot read property 'toLowerCase' of null
This is the function I try to run:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.createNewUser = functions.auth.user().onCreate((user) => {
let lowerCaseEmail = user.email.toLowerCase();
return admin.database().ref(`/users/${user.uid}/lowerCaseEmail`).set(lowerCaseEmail);
});
I believe I don't invoke my custom function correctly in firebase functions:shell.
Would someone like to point me in the right direction?

As per the documentation you have to pass a UserRecord (see doc) when invoking an Auth function, see at the bottom of the doc you point to in your Question (i.e. https://firebase.google.com/docs/functions/local-emulator#invoke_realtime_database_functions)
Doing the following works:
createNewUser({ disabled: false,
displayName: 'Renaud',
email: 'Mail#Gmail.com',
emailVerified: false,
metadata: {creationTime: null, lastSignInTime: null},
photoURL: null,
providerData: ['google.com'],
uid: '123' })
You do find the new record in the database, with the email in lower case.
Actually, since the documentation says: "Specify only the fields that your code depends on, or none at all if you only want to run the function.", I've tried with the following UserRecord object, and it also works.
createNewUser({email: 'Mail#Gmail.com', uid: '123'})

Related

google cloud function deploying failed functions: cleaning up build files

when i tried to deployed the cloud functions. i am facing the error below..
before update the node version it was working fine
node#14
firebase cli up-to date
nom also up-to date
const functions = require('firebase-functions')
const admin = require('firebase-admin');
const nodemailer = require('nodemailer');
const cors = require('cors')({ origin: true });
admin.initializeApp()
exports.sendcertificate = functions.firestore.document('certificate/{docId}')
.onCreate((snap: { data: () => any; }, ctx: any) => {
const data = snap.data();
let authData = nodemailer.createTransport({
host: 'mail.bacttraining.com',
port: 465,
secure: true, // use SSL
auth: {
user: *******',
pass: *******',
},
});
authData.sendMail({
from: ********,
to: *********,
Bcc: '*******',
sender: "*******",
subject: "Certificate Request",
text: `${data.course}`,
html: *******,
}).then(console.log("email send sussfully"))
.catch(console.error('we cant send email : ', console.error()
));
}
);**strong text**
Make sure your CLI tools are up to date, and that your modules in use are the latest. I can see that the console is warning you that cloud functions are outdated.
Then ensure all functions that did not deploy for any bugs and syntax errors as the cloud functions uploader can crash if the code was packed incorrectly.
Once the above has been done, you can try deploying the functions one at a time with
firebase deploy --only functions:functionName
This will narrow any functions that have bugs or syntax errors down.
This issue occurs when there is difference in the node version you have installed in the system and the node engine version mentioned in package.json file.
Please check your node version using
node -v
Make sure you have mentioned the same engine version in package.json

How to stub external services in Firebase emulator?

I have one firestore trigger function that is creating DNS record based on the slug attribute. I have some unit tests where I am stubbing #google-cloud/dns module so no external HTTP request is made. However, I have several integration tests as well. Those are hitting local firebase emulator (localhost:8080).
For instance, whilst testing firestore rules, I am simply calling db.collection('path').add(model) and that is triggering callable function inside emulator process.
Tests are running by this command: firebase emulators:exec 'mocha --config spec/.mocharc.yml
At first, it is initializing emulators and then running tests. As far as I understood these are different processes. So inside the mocha process, I am able to stub, mock with modules. On the other hand, inside the emulator process, functions, modules, dependencies are already loaded as it is. So when I am running this test script for testing firestore rules inside mocha test suite:
await assertSucceeds(db.doc('stores').set(store));
It actually runs the handler and sends the request to the google cloud DNS. Did anyone face issues something like this? Thanks in advance.
I'm facing the same situation. My plan is to make the Cloud Function initialize itself with a stubbed service that will record its own calls to a log collection in Firestore when NODE_ENV=test. Then the test will check whether the call was recorded by querying that collection.
test('fanOutCategoryFields', async () => {
// Initialize Firebase and seed test data
const app = await setup({
'categories/1': {
name: 'Some Name',
},
'posts/1': {
categoryId: '1',
},
})
// Update a document (will trigger the Cloud Function)
await app
.firestore()
.collection('categories')
.doc('1')
.update({ name: 'New Name' })
// Wait for the Cloud Function to run
await new Promise(resolve => setTimeout(resolve, 3000))
// Query the collection where function calls are recorded
const calls = await app
.firestore()
.collection('_calls')
.get()
.then(snap => snap.docs.map(snap => snap.data()))
// Check if Algolia was called with the expected arguments
expect(calls).toEqual([
{
fn: 'algolia.update',
args: ['products', '1', { categoryName: 'New Name' }],
},
])
})

Firestore in Cloud Functions - Create a missing index through an error message

When using Firestore in Cloud Functions, how to use the Create a missing index through an error message feature?
Basically, after I use a new Firestore query in my Cloud Function, where should I expect to find the "error message [that] includes a direct link to create the missing index"?
Update: add sample code based on a comment suggestion
Assume the query below wasn't used before. After I deploy the function to Cloud Functions and use it, where can I find the automatically-created link for creating the missing index?
import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
export const posts = functions.https.onCall(async (
data: { uid: string },
context
) => {
// ...
const querySnapshot = await postsRef
.where('uid', '==', data.uid)
.orderBy('timestamp', 'desc')
.get();
// ...
});
When you perform the query, the resulting promise will become rejected. Your code will need to catch that error from the rejected promise, then log the error object. The url will be in the log message. (I'm assuming you're using node here, but the same error handling will apply to any language using its conventions for capturing and logging errors.)

Should firebase auth onCreate trigger have more data?

I'm using functions.auth.user().onCreate() as part of a firestore project, and trying to set up some default data when a new user registers. For the front end, I'm using firebase-ui, with Google and Email/Password providers enabled.
When I sign in with an email and password, the UI widget prompts to enter a name and set a password. I was expecting to see the name as part of the user parameter in the onCreate() function call, but I'm getting practically nothing:
user: { email: 'xxx#yyyy.co.uk',
emailVerified: false,
displayName: null,
photoURL: null,
phoneNumber: null,
disabled: false,
providerData: [],
customClaims: {},
passwordSalt: null,
passwordHash: null,
tokensValidAfterTime: null,
metadata:
UserRecordMetadata {
creationTime: '2018-11-20T15:06:01Z',
lastSignInTime: '2018-11-20T15:06:01Z' },
uid: 'QDJ5OJTwbvNo2QNDVQV9VsxC2pz2',
toJSON: [Function] }
Not even getting the provider info so I can tell which 'kind' of user registered. It's almost like this function is triggered before the user record has been populated (except the email address does get through). Also, registrations via the Google provider come with a fully-populated user record, so I guess this is a problem with Email/Password specifically.
Is this a bug, or am I missing something? I didn't see anything else useful in the context parameter either.
The fact that displayName is not populated in the Cloud Functions onCreate trigger for email+password is expected. The function is triggered from the first API call (createUserWithEmailAndPassword()), while the display name is set with a second API call (updateProfile).
The usual workaround would be to create a Cloud Function to update the user profile, as shown here: Firebase Auth+Functions | create user with displayName
I also highly recommend filing a feature request to be able to have a Cloud Function triggered on profile changes.

Firebase functions - Deploy Completed but doesn't exist in Firebase

Follow the guide of using Cloud Functions with Firebase.
Setup environment
setup project in Firebase
Created function
command prompt writes that function deployed, but firebase is empty.
I am new with deploying functions so I am sure that it is stupid question and I think I did something wrong in setting up but I checked three times different guides and it looks everything done right. So please if you know what the problem it is can be?
I used this guide and there I done everything till initializing the project
https://firebase.google.com/docs/functions/get-started
After that in index.js I wrote a function
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(function.config().firebase);
export.sendNotification = functions.database
.ref('/notifications/{user_id}/{notification_id}')
.onWrite(event => {
conts user_id = event.params.user_id;
const notification = event.params.notification_id;
if(!event.data.val()){
return console.log('A notification has been deleted ', notification_id);
}
const payload = {
notification: {
title: "Friend Request",
body: "Received new Friend Request",
icon: "default"
}
};
return admin.messaging().sendToDevice(/*Token*/, payload).then(response =>{
console.log('');
});
});
And with the command
firebase deploy
I tried to deploy function
But in firebase cattegory "Function" it is still empty
Error in CMD
There is syntax error, Please change below line in your code
admin.initializeApp(function.config().firebase);
to
admin.initializeApp(functions.config().firebase);
I'm quite late here but it might help somebody else. You're right, it is typo. The correct command is:
exports
not
export

Resources