Unable to get user by email using Cloud Function for Firebase - javascript

I am using the Node.js Admin SDK within a Cloud Function for Firebase and I want to call the admin.auth().getUserByEmail() method.
Since I'm using a Cloud Function I read here that I only need to call admin.initializeApp(functions.config().firebase); which you can see below I've done.
However, when I call the getUserByEmail() (only tested locally) I get the following error:
'No Firebase project was found for the provided credential.'
Here's my index.js
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.hello = functions.https.onRequest(function (req, resp) {
var from = req.body.sender;
admin.auth().getUserByEmail(from)
.then(function (userRecord) {
// See the UserRecord reference doc for the contents of userRecord.
console.log("Successfully fetched user data:", userRecord.toJSON());
})
.catch(function (error) {
console.log("Error fetching user data:", error);
})
});
Has anyone got any experience of this and can tell me what I'm doing wrong?

The admin sdk won't get proper config json if you are using localy(in google cloud functions emulator). You have to use your service account json obtained from firebase console.
But if you have deployed it, your method will work just fine.

Related

Why I can't fetch data from a api in javascript? It shows deploy created successfully. But while running in firebase cloud function, it doesn't work

I want to implement firebase cloud messaging via firebase cloud function so that I can send message to every users which have installed my android application. The message would be a value of a key of json object from this url <[https://coronavirus-19-api.herokuapp.com/countries/bangladesh]>.
Click the text below to see the image of json object
json object
In my case, I want to send the value of the key "todayDeaths" through firebase cloud message. When I try to call the json by api method and fetch the data of it and set this in message in index.js file, it showed no error and deploy created. But when I try to check the status of my function ,it shows error.
Click the text below to see the image of error showed in Logs of firebase cloud function.
firebase cloud function Logs.
I will add the index.js code below:
const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.scheduledFunction = functions.pubsub.schedule('every 2 minutes').onRun(async (context)
=> {
const response=await axios.get(
'https://coronavirus-19-api.herokuapp.com/countries/bangladesh'
);
console.log(response.data);
const body=response.todayDeaths;
const message = {
notification: {
'title': 'Today death',
'body': body,
},
topic:'allUser'
};
admin.messaging().send(message)
.then(response=>{
console.log("Successfully sent",response);
}).catch(error=>{
console.log("failed",response);
});
console.log('This will be run every 2 minutes!');
return null;
});
How can I solve the problem so that the firebase cloud messaging successfully send the message to all of the users of the project?
It looks like you just forgot to import axios.
Add this to the top:
const axios= require('axios');

Firebase forbidden GET url response on init

Have deployed a few firebase functions (according to docs)
firebase init
Changed the code to something like
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.getUsers = functions
.region('europe-west1')
.https.onRequest((req, res) => {
admin.firestore().collection('users').get().then(data => {
const users = data.map(user => user.data());
return res.json(users);
}).catch(err => console.error(err));
});
exports.helloWorld = functions.https.onRequest((req, res) => {
res.status(200).send('Hello, World!');
});
Deployed it.
firebase deploy
And as an end result both of the functions return
Error: Forbidden Your client does not have permission to get URL
/getUsers from this server.
Error: Forbidden Your client does not have permission to get URL
/helloWorld from this server.
In the firebase admin console I see that functions exist, and they are there, and I am using same exact urls that the terminal gave me & are on the firebase admin console.
Any ideas?
PS. Located in Estonia.
Alright,
To solve this issue I had to use my brain and check the dashboard for cloud functions. Cloud functions do not return a 500 error unlike most common APIs, instead inside of the dashboard I found out that:
TypeError: data.map is not a function
admin.firestore.collection.get.then.data ( /user_code/index.js:10 )
Meaning my 'application' was crashing, oddly enough it was giving me a 403 error.
For good measure I also followed this:
Firebase cloud function "Your client does not have permission to get URL /200 from this server"

Calling firebase function results in Internal Error

I am calling a simple firebase function from a web app I get an INTERNAL error. Can someone please suggest where I could be going wrong.
I have seen similar questions but they don't answer the issue I am facing.
I can confirm that the function has been deployed to the firebase.
By pasting the below link in the browser I get a response.
https://us-central1-cureme-dac13.cloudfunctions.net/helloWorld
index.js file has the code (Firebase cloud functions are defined in index.js)
const functions = require('firebase-functions');
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
webApp.js has the below code (Client/Website)
var messageA = firebase.functions().httpsCallable('helloWorld');
messageA().then(function(result) {
console.log("resultFromFirebaseFunctionCall: "+result)
}).catch(function(error) {
// Getting the Error details.
var code = error.code;
var message = error.message;
var details = error.details;
// ...
console.log("error.message: "+error.message+" error.code: "+error.code+" error.details: "+error.details)
// Prints: error.message: INTERNAL error.code: internal error.details: undefined
});
You are mixing up Callable Cloud Functions and HTTPS Cloud Functions.
By doing
exports.helloWorld = functions.https.onRequest(...)
you define an HTTPS Cloud Function,
but by doing
var messageA = firebase.functions().httpsCallable('helloWorld');
messageA().then(function(result) {...});
in your client/front-end, you actually call a Callable Cloud Function.
You should either change your Cloud Function to a Callable one, or call/invoque the helloWorld HTTPS Cloud Function by sending an HTTP GET Request to the Cloud Function URL (Similarly to the way you did in your browser by "pasting the https://us-central1-cureme-dac13.cloudfunctions.net/helloWorld link in the browser").
For example, by using the Axios library, you would do:
axios.get('https://us-central1-cureme-dac13.cloudfunctions.net/helloWorld')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})

How to send push notification from angular 6 project to android app

I have an android app in which I send push notification using firebase admin sdk with nodejs.
I was able to send notification from the nodejs raw script when I ran the script.
However, I just built an admin dashboard for sending notification to the app with angular 6 but don't know how to integrate the nodejs script with the new angular app so that I can send notification from the angular app by just a click.
I'd also encourage new ideas on how best to to this.
attached is a screenshot from the nodejs admin script
Setup your node to behave as API server, using Express for example.
Wrap your script as Express module (named send-message.js), basically just make that a function that you export:
const sendMessage = (...params) => {
//your send message logic, I would do copy paste of your code here however it is an image
}
module.exports = sendMessage;
Well and then setup API route that calls the script:
var express = require('express')
var sendMessage = require('./send-message')
var app = express()
app.get('/send-message', function (req, res) {
sendMessage(....);
res.status(200).end();
})
app.listen(3000)
And finally in Angular use HttpClient to call the API.
I finally solved the problem by using firebase cloud functions.
First I set up cloud functions on firebase with this guide
Then I created a cloud function named sendNotification() which is triggered each time new objects are inserted to the firebase realtime database.
Then I placed my existing notification code inside sendNotification() function
Deployed the function to my firebase console
Then hurray, the notification was sent to my device after some db triggers
`
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
//This functions listens to the node '/Food menu/date/Food' for new insert and sends notification to a client
exports.sendNotification = functions.database.ref('/Food menu/date/Food')
.onCreate((snapshot, context) => {
//place your client app registration token here, this is created when a user first opens the app and it is stored in the db.
//You could also retrieve the token from the db but in this case it is hard coded
var registrationToken = "{my-registration-token}";
//This is the payload for notification
var payload = {
data: {
'title': 'Tomorrow\'s Menu',
'message': 'Hello, kindly check the menu available for today',
'is_background': 'true',
'image': 'http://www.allwhitebackground.com/images/3/3430.jpg',
'timestamp': '234'
}
};
// Send a message to the device corresponding to the provided
// registration token.
admin.messaging().sendToDevice(registrationToken, payload)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
//return a promise here since this function is asynchronous
return "Yes";
})
.catch((error) => {
console.log('Error sending message:', error);
});
//return snapshot.ref.parent.child('uppercaseFood').set(uppercase);
});
`
After this, you run firebase deploy --only functionsto deploy the cloud function
Read this guide for more info on cloud functions

firebase.auth(...).signInWithEmailAndPassword is not a function in Cloud Function

I m getting Error while invoked function.
I m using LsignInWithEmailAndPassword Method.Any Special Configuration is Require?
const functions = require('firebase-functions');
const firebase=require('firebase-admin');
firebase.initializeApp(functions.config().firebase);
exports.login = functions.https.onRequest((request, response) => {
var data = {
email : 'demo#gmail.com',
password : 'demo123'
};
var auth = null;
firebase
.auth()
.signInWithEmailAndPassword(data.email, data.password)
.then( function(user){
response.send("Authenticated successfully with payload");
// console.log("Authenticated successfully with payload:", user);
auth = user;
})
.catch(function(error){
response.send("Login Failed!");
// console.log("Login Failed!", error);
});
// response.send("Hello from Firebase!");
});
When you call firebase.auth() from the Admin SDK, you're getting an object of type Auth. As you can see from the API docs, it doesn't have a method called signInWithEmailAndPassword.
It seems you're mixing up the javascript client SDK with the Admin SDK. There's no reason to use the client SDK in Cloud Functions. It's supposed to be used in the browser only, since signing in only makes sense on the device that the user is actually using.
signInWithEmailAndPassword is only available in a browser environment. To get access to who made a particular request, you can use firebase.auth().getToken to get a JWT token, and send that along to your cloud function endpoint. Then from there you can call verifyIdToken to get the uid of whoever made the request.

Categories