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
Related
I am trying to install firebase functions so I can implement payment apis into my app.
Yet I am going through multiple tutorials and going through firebase manuals on how to install functions and get it working.
I am getting stuck here in terminal....
lukasbimba#Lukass-iMac functions % firebase deploy --only functions
(node:51250) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created).
⚠ functions: package.json indicates an outdated version of firebase-functions.
Please upgrade using npm install --save firebase-functions#latest in your functions directory.
=== Deploying to 'shoppeer-e7270'...
i deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint
> functions# lint /Users/lukasbimba/Desktop/Xcode Projects/ShopPeer/functions/functions
> eslint .
✔ functions: Finished running predeploy script.
i functions: ensuring necessary APIs are enabled...
Error: HTTP Error: 404, Method not found.
Having trouble? Try firebase deploy --help
lukasbimba#Lukass-iMac functions %
index.js file
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
// // Create and Deploy Your First Cloud Functions
https://firebase.google.com/docs/functions/write-firebase-functions
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
// Grab the text parameter.
const original = req.query.text;
// Push the new message into Firestore using the Firebase Admin SDK.
const writeResult = await admin.firestore().collection('messages').add({original: original});
// Send back a message that we've successfully written the message
res.json({result: `Message with ID: ${writeResult.id} added.`});
});
// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore.document('/messages/{documentId}')
.onCreate((snap, context) => {
// Grab the current value of what was written to Firestore.
const original = snap.data().original;
// Access the parameter `{documentId}` with `context.params`
functions.logger.log('Uppercasing', context.params.documentId, original);
const uppercase = original.toUpperCase();
// You must return a Promise when performing asynchronous tasks inside a Functions such as
// writing to Firestore.
// Setting an 'uppercase' field in Firestore document returns a Promise.
return snap.ref.set({uppercase}, {merge: true});
});
running
curl -sL https://firebase.tools | bash
then running
curl -sL firebase.tools | upgrade=true bash
run this if your firebase versions are not saving
I'm trying to integrate Sendgrid's Email API with my Firebase webapp. Here is what I've done:
1 - Installed Sendgrid's Mail package
npm install #sendgrid/mail
2 - Created an API Key on my Sendgrid Account
3 - Assigned the API Key to an environment variable using Firebase's environment configuration:
firebase functions:config:set sendgrid.key=SG.xxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx_xxxxxx_xxxxxxxxxxxxxxx
4 - checked to see if the environment variable was correctly assigned:
firebase functions:config:get
result:
5 - imported sendgrid mail and set API key:
import * as sgMail from '#sendgrid/mail';
const API_KEY = functions.config().sendgrid.key
const TEMPLATE_ID = functions.config().sendgrid.template
sgMail.setApiKey(API_KEY);
6 - created a new user trigger to send a test email
export const welcomeEmail = functions.auth.user().onCreate(user => {
const msg = {
to: user.email,
from: 'contato#mycompanydomain.com.br',
templateId: TEMPLATE_ID,
dynamic_template_data: {
subject: 'test subject!',
name: user.displayName,
},
};
return sgMail.send(msg);
})
7 - Deployed firebase functions:
firebase deploy --only functions
After doing this I'd expect that at least the API key would be set correctly, but I keep getting the following error from firebase functions log:
I can't figure out what is wrong. I've tried a few things:
1- creating a new api key and starting the process all over.
2- pasting the API directly into the sgMail.setApiKey() method. like:
sgMail.setApiKey("SG.xxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx_xxxxxx_xxxxxxxxxxxxxxx")
All of which gave the same "API key does not start with SG" error.
Can you guys help me figure out what's wrong?
Versions
"#sendgrid/mail": "^7.2.1",
"firebase-admin": "^8.10.0",
"firebase-functions": "^3.8.0"
Thank you so much
For does who had the same problem, I solved it by using the new firebase package and importing the config from firebase-functions.
So my code looks like this:
import functions, { config } from "firebase-functions";
import sendgrid from "#sendgrid/mail";
const MY_SENDGRID_API_KEY = config().sendgrid.key;
sendgrid.setApiKey(MY_SENDGRID_API_KEY);
According to the following google I/O (2019) post of the firebase team the new emulator allows us to combine firebase/database plus cloud function to fully simulate our firebase server codes. That should also mean we should be able to write tests for it.
we’re releasing a brand new Cloud Functions emulator that can also
communicate with the Cloud Firestore emulator. So if you want to build
a function that triggers upon a Firestore document update and writes
data back to the database you can code and test that entire flow
locally on your laptop (Source: Firebase Blog Entry)
I could find multiple resources looking/describing each individual simulation, but no all together
Unit Testing Cloud Function
Emulate Database writes
Emulate Firestore writes
To setup a test environment for cloud functions that allows you to simulate read/write and setup test data you have to do the following. Keep in mind, this really simulated/triggers cloud functions. So after you write into firestore, you need to wait a bit until the cloud function is done writing/processing, before you can read the assert the data.
An example repo with the code below can be found here: https://github.com/BrandiATMuhkuh/jaipuna-42-firebase-emulator .
Preconditions
I assume at this point you have a firebase project set up, with a functions folder and index.js in it. The tests will later be inside the functions/test folder. If you don't have project setup use firebase init to setup a project.
Install Dependencies
First add/install the following dependencies: mocha, #firebase/rules-unit-testing, firebase-functions-test, firebase-functions, firebase-admin, firebase-tools into the functions/package.json NOT the root folder.
cd "YOUR-LOCAL-EMULATOR"/functions (for example cd C:\Users\User\Documents\FirebaseLocal\functions)
npm install --save-dev mocha
npm install --save-dev firebase-functions-test
npm install --save-dev #firebase/rules-unit-testing
npm install firebase-admin
npm install firebase-tools
Replace all jaipuna-42-firebase-emulator names
It's very important that you use your own project-id. It must be the project-id of your own project and must exists. Fake ids won't work. So search for all jaipuna-42-firebase-emulator in the code below and replace it with your project-id.
index.js for an example cloud function
// functions/index.js
const functions = require("firebase-functions");
const admin = require("firebase-admin");
// init the database
admin.initializeApp(functions.config().firebase);
let fsDB = admin.firestore();
const heartOfGoldRef = admin
.firestore()
.collection("spaceShip")
.doc("Heart-of-Gold");
exports.addCrewMemeber = functions.firestore.document("characters/{characterId}").onCreate(async (snap, context) => {
console.log("characters", snap.id);
// before doing anything we need to make sure no other cloud function worked on the assignment already
// don't forget, cloud functions promise an "at least once" approache. So it could be multiple
// cloud functions work on it. (FYI: this is called "idempotent")
return fsDB.runTransaction(async t => {
// Let's load the current character and the ship
const [characterSnap, shipSnap] = await t.getAll(snap.ref, heartOfGoldRef);
// Let's get the data
const character = characterSnap.data();
const ship = shipSnap.data();
// set the crew members and count
ship.crew = [...ship.crew, context.params.characterId];
ship.crewCount = ship.crewCount + 1;
// update character space status
character.inSpace = true;
// let's save to the DB
await Promise.all([t.set(snap.ref, character), t.set(heartOfGoldRef, ship)]);
});
});
mocha test file index.test.js
// functions/test/index.test.js
// START with: yarn firebase emulators:exec "yarn test --exit"
// important, project ID must be the same as we currently test
// At the top of test/index.test.js
require("firebase-functions-test")();
const assert = require("assert");
const firebase = require("#firebase/testing");
// must be the same as the project ID of the current firebase project.
// I belive this is mostly because the AUTH system still has to connect to firebase (googles servers)
const projectId = "jaipuna-42-firebase-emulator";
const admin = firebase.initializeAdminApp({ projectId });
beforeEach(async function() {
this.timeout(0);
await firebase.clearFirestoreData({ projectId });
});
async function snooz(time = 3000) {
return new Promise(resolve => {
setTimeout(e => {
resolve();
}, time);
});
}
it("Add Crew Members", async function() {
this.timeout(0);
const heartOfGold = admin
.firestore()
.collection("spaceShip")
.doc("Heart-of-Gold");
const trillianRef = admin
.firestore()
.collection("characters")
.doc("Trillian");
// init crew members of the Heart of Gold
await heartOfGold.set({
crew: [],
crewCount: 0,
});
// save the character Trillian to the DB
const trillianData = { name: "Trillian", inSpace: false };
await trillianRef.set(trillianData);
// wait until the CF is done.
await snooz();
// check if the crew size has change
const heart = await heartOfGold.get();
const trillian = await trillianRef.get();
console.log("heart", heart.data());
console.log("trillian", trillian.data());
// at this point the Heart of Gold has one crew member and trillian is in space
assert.deepStrictEqual(heart.data().crewCount, 1, "Crew Members");
assert.deepStrictEqual(trillian.data().inSpace, true, "In Space");
});
run the test
To run the tests and emulator in one go, we navigate into the functions folder and write yarn firebase emulators:exec "yarn test --exit". This command can also be used in your CI pipeline. Or you can use npm test instead.
If it all worked, you should see the following output
√ Add Crew Members (5413ms)
1 passing (8S)
For anyone struggling with testing firestore triggers, I've made an example repository that will hopefully help other people.
https://github.com/benwinding/example-jest-firestore-triggers
It uses jest and the local firebase emulator.
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'})
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