Deploy or Run Functions Locally (HTTP functions + Realtime Database functions ) - javascript

How can I run HTTP functions and Realtime Database functions simultaneously
I see in the documentation here : Run functions locally how to run HTTP functions by the following command : firebase serve and for the Realtime Database functions : firebase functions:shell but it doesn't work for me.
And also when I deployed my functions with command firebase deploy --only functions it only deploy my HTTP function .
What is wrong with my approach ?
structure:
/functions
|--index.js
|--saveDetectedBeacons.js
|--generatePresence.js
|--package.json
index.js:
const functions = require('firebase-functions');
const admin = require("firebase-admin");
const saveDetectedBeaconsFunc = require('./saveDetectedBeacons');
const generatePresenceFunc = require('./generatePresence');
const serviceAccount = require("./serviceAccountKey");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://exampleDb.firebase.com"
});
const db = admin.database();
exports.saveDetectedBeaconsApi = functions.https.onRequest((request, response) => {
saveDetectedBeaconsFunc.handler(request,response,db)
});
exports.generatePresenceApi = functions.database.ref('/reports').onCreate((snapshot, context) => {
generatePresenceFunc.handler(snapshot, context, db)
});
saveDetectedBeacons.js:
exports.handler = function (request, response, db) {
// do something
};
generatePresence.js
exports.handler = function (snapshot, context, db) {
// do something
};

Related

Set timeout for Firebase HTTPS Cloud Function

As per the documentation you can specify the timeout for a function like so:
const runtimeOpts = {
timeoutSeconds: 300,
memory: '1GB'
}
exports.myStorageFunction = functions
.runWith(runtimeOpts)
.storage
.object()
.onFinalize((object) = > {
// do some complicated things that take a lot of memory and time
});
However, the following code fails to deploy, with error TypeError: functions.https.runWith is not a function:
const admin = require("firebase-admin");
const functions = require("firebase-functions");
admin.initializeApp();
exports.hello = functions.runWith({ timeoutSeconds: 540 }).https.onRequest(async (req, res) => {
res.send("hello");
});
What is wrong?

Firebase cloud functions not updating when deployed - still serving old version of function

I'm frustrated and confused. I'm trying to deploy my cloud functions but whenever I do they're not updating properly and despite firebase saying that they were updated successfully, keep serving the old function. Here's my index.js:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
//Cloud functions for user interaction
const charge = require('./func/charge');
const addProduct = require('./func/addProduct');
const removeProduct = require('./func/removeProduct');
const updateTracking = require('./func/updateTracking');
admin.initializeApp(functions.config().firebase);
exports.charge = functions.https.onRequest(charge);
exports.updateTracking = functions.https.onRequest(addProduct);
exports.addProduct = functions.https.onRequest(removeProduct);
exports.removeProduct = functions.https.onRequest(updateTracking)
And here's my addProduct function with everything stripped away. This still doesn't update.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const request = require('request');
const send = require('../send.js');
const cors = require('cors')({origin: '*'});
function addProduct(req, res) {
console.log('THIS NEVER PRINTS')
send(res, 500, {
error: `FAILURE`
})
}
const appAddProduct = express();
appAddProduct.use(cors);
appAddProduct.post('/', (req, res) => {
// Catch any unexpected errors to prevent crashing
try {
addProduct(req, res);
} catch(e) {
console.log(e);
send(res, 500, {
error: `The server received an unexpected error. Please try again and contact the site admin if the error persists.`,
});
}
});
module.exports = appAddProduct
This is still serving up a success message & status code 200 from an older function with a logic error in it when this should just be serving up a 500 error every time. Something is clearly wrong with the way I've split this into multiple files as that is where the trouble started but I'm not sure where I've gone wrong. Help would be much appreciated.
Your exported function names don't match the names of the imported files:
exports.charge = functions.https.onRequest(charge);
exports.updateTracking = functions.https.onRequest(addProduct);
exports.addProduct = functions.https.onRequest(removeProduct);
exports.removeProduct = functions.https.onRequest(updateTracking)
I see that three of the four functions are not paired with the same-named imports. The only one that matches is charge. I suspect you didn't intend to do this.

Firebase authentication, firebase is not defined

Im trying to make a login page to my firebase project, but always when i send the params to the functions its returns "Firebase is not defined . Here's my code:
<button id="login" onclick="signIn()"><Login</button>
The function signIn() only change the href to http://localhost:5000/signin/:email/:password
then i have this
const functions = require('firebase-functions');
const adm = require('firebase-admin');
const express = require('express');
const signin = require('./modules/signin');
const firebase = require("firebase");
// // Create and Deploy Your First Cloud Functions
adm.initializeApp(
functions.config().adm
);
const app = express();
app.get('/signin/:email/:password', (request, response) => {
exports.signin = signin(request.params.email, request.params.password);
});
exports.app = functions.https.onRequest(app);
and my function is only
function signin (email, password) {
firebase.auth().signInWithEmailAndPassword(email, password).then(function(user) {
// user signed in
console.log ("Usuário logado com sucesso!");
return True;
}).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode === 'auth/wrong-password') {
// alert('Wrong password.');
return false;
} else {
alert(errorCode+": "+errorMessage);
return false;
}
});
}
module.exports = signin;
im trying to use the index.js on functions folder as a type of "controller" to call functions on backend, but im having trouble to solve this simple problem.
You can't use the Firebase client SDK in Cloud Functions. Cloud Functions is considered backend code, and doesn't run on the browser. If you want to sign in the user, you have to use the SDK in your browser code, not backend code.

Express.js: create additional mongodb DB in controller

I'm new to MongoDB.
When I create my node.js server I use only one DB connection (on start I connect to it).
But imagine: I have one database with some generic tables, and more databases - each for a custom client.
How can I create those DB at runtime?
start.js:
const mongoose = require("mongoose");
// import environmental variables from variables.env file
require("dotenv").config({ path: "variables.env" });
mongoose.connect(process.env.DATABASE);
mongoose.Promise = global.Promise;
mongoose.connection.on("error", err => {
console.error(`🚫 → ${err.message}`);
});
require("./models/MaintenanceType");
require("./models/Maintenance");
const app = require("./app");
app.set("port", process.env.PORT || 7777);
const server = app.listen(app.get("port"), () => {
console.log('started');
});
variables.env (example):
NODE_ENV=development
DATABASE=mongodb://db:qwe123#sometest.server.com:412345/webtest
PORT=1234
SECRET=webtest
KEY=webtestcom
and controller:
const mongoose = require("mongoose");
const Maintenance = mongoose.model("Maintenance");
exports.createMaintenance = async (req, res) => {
const maintenance = await new Maintenance(req.body).save();
// ALSO create a db and table if not exists for this client and use it somehow
res.json(maintenance);
};
is it possible to do?
You can create new connection
mongoose.connect('URI_FOR_ANOTHER_DATABASE')
But it's bad idea to create new connections, so the driver has a feature to use existing connections to query another database, for this purpose you can check useDb() method as shown here

How to use Admin SDK with limited privileges on Firestore?

I have some trouble with Cloud function and firestore rules.
I would like use cloud function with limited privilèges on Firestore and give
only has access as defined in the Security Rules
It's working without problem on RTDB but not on Firestore.
I have try with this rules
service cloud.firestore {
match /databases/{database}/documents {
match /init/{ID=**} {
allow read, write: if true;
}
match /test/{ID=**} {
allow read, write: if false;
}
}
}
And this
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const FieldValue = require('firebase-admin').firestore.FieldValue;
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://******.firebaseio.com',
databaseAuthVariableOverride: {
uid: 'my-worker',
},
});
const db = admin.firestore();
exports.onTestRights = functions.firestore
.document('init/{initID}')
.onCreate((event) => {
const initID = event.params.initID;
return db.collection('test').doc(initID).set({'random key': 'random value'}).then(()=>{
console.log('working');
return;
}).catch((err) =>{
console.log('error: ', err);
return;
});
});
But it's still writing so whereas it should be "permission denied"
Anyone know if it's normal(or not yet implanted) on firestore or I have misunderstood something ?
Edit:
Of course my final goal is not with this rules, but only give write/read access on some documents/collections using (allow read, write: if request.auth.uid == 'my-worker';)
Edit2:
I would like use the security rules for checking like a transaction if no change during process using this model
As you've noticed databaseAuthVariableOverride only works for the Realtime Database. There is nothing right now that allows you to do the same for Firestore in the Admin SDK.
One workaround you could use if you want to limit the access rights on your server code is to use the Client JS SDK rather than Firebase Admin and sign the user-in using a custom token. Here is a sample code to do this:
// Configure Firebase Client SDK.
const firebase = require('firebase/app');
require('firebase/auth');
require('firebase/firestore');
firebase.initializeApp({
// ... Initialization settings for web apps. You get this from your Firebase console > Add Firebase to your web app
});
// Configure Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
// Create Custom Auth token for 'my-worker'.
const firebaseReady = admin.auth().createCustomToken('my-worker').then(token => {
// Sign in the Client SDK as 'my-worker'
return firebase.auth().signInWithCustomToken(token).then(user => {
console.log('User now signed-in! uid:', user.uid);
return firebase.firestore();
});
});
// Now firebaseReady gives you a Promise that completes with a authorized firestore instance. Use it like this:
exports.onTestRights = functions.firestore
.document('init/{initID}')
.onCreate(event => {
const initID = event.params.initID;
return firebaseReady.then(db => db.collection('test').doc(initID).set({'random key': 'random value'}).then(() => {
console.log('working');
return;
}).catch((err) =>{
console.log('error: ', err);
return;
});
);
});

Categories