Firebase cloud function always fails - onerror - firebase

I am trying to call firebase cloud function using xmlhttprequest through serve feature(testing locally), the following code is xmlHttpRequest
var req = new XMLHttpRequest();
req.onload = function() {
//success
};
req.onerror = function() {
//always fall to this function
};
var url = 'https://us-central1-' + getFirebaseProjectId() + '.cloudfunctions.net/helloWorld';
req.open('GET', url);
//Chrome does not allow 'Access-Control-Allow-Origin' from
//localhost:5000 (non-google server)
//I am using mozilla firefox with 'serve' feature, hope
//this solve 'Access-Control-Allow-Origin' problem
req.setRequestHeader('Access-Control-Allow-Origin', '*');
req.send();
I can see that cloud function is executed successfully in firebase console. But i am always fall into onerror function.
I also enabled CORS in cloud functions by
const cors = require('cors')({origin: true});
While hosting functions locally i get following error
After research of two day of research ,
Updated node and firebase to compatible version.
Cleared cache
Updated firebase-tools, firebase functions through npm
. Still not working.

Delete the project, re-initialize the project with firebase init function. hope this helps.

Related

How to fix Firebase CORS errors in callable functions? [duplicate]

This question already has answers here:
Firebase Callable Function + CORS
(21 answers)
Closed 1 year ago.
I have a problem with Firebase and CORs, apparently it cannot reach the endpoint with errors like:
Access to fetch at
'https://europe-west2-XXX.cloudfunctions.net/fetchChatToken'
from origin 'https://trato.app' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
service.ts:203
POST
https://europe-west2-XXX.cloudfunctions.net/fetchChatToken
net::ERR_FAILED (anonymous) # service.ts:203 ... ...
error.ts:66 Uncaught (in promise) Error: internal
at new t (error.ts:66)
at error.ts:175
at e. (service.ts:276)
at tslib.es6.js:100
at Object.next (tslib.es6.js:81)
at a (tslib.es6.js:71)
I also checked the network tab on dev inspector (chrome) to check if the CORS header is there, i dont see it.
Also, I have been checking firebase functions logs and apparently is not being even invoked, the last line showing is the deployment.
the way that Im using it is this:
Front End side:
const functions = firebaseApp.functions('europe-west2');
export const fetchChatToken = async () => (await functions.httpsCallable('fetchChatToken')()).data;
Functions (Backend) side:
const ensureAuthentication = auth => { if (!auth) throw new HttpsError("unauthenticated", "authentication required"); };
exports.fetchChatToken = functions.region("europe-west2").https.onCall((data, context) => {
ensureAuthentication(context.auth);
try {
const { AccessToken } = twilio.jwt;
const { ChatGrant } = AccessToken;
const grant = new ChatGrant({
serviceSid: conversationsid
});
const token = new AccessToken(accountsid, apikey, apisecret);
token.addGrant(grant);
token.identity = context.auth.uid;
return token.toJwt();
} catch (error) {
console.error(error);
throw new HttpsError("internal", "internal error");
} });
Unfortunately there many reasons possible for this CORS error. If the cloud function returns an "internal" error message it might be due to inconsistent Regions or errors in your cloud function code. My checklist for this error when creating a new cloud function:
Not matched Regions of Firestore-Project, Functions and Client side init cause a CORS Error
internal code errors inside the cloud functions cause this error
new function must be included in cloud function index file (if used)
cloud function name must match the string on client side invocation
delete cloud function in firebase dashboard before deploying new one after error
Make sure the function name referenced in the client is correct, see https://stackoverflow.com/a/62042554/1030246
I got it solved changing it to us, basically removing the region, taking out the 'europe-wes2' region from the function declaration and from the function call it works fine again.
I assume there is some error on the firebase side.

Cloud Functions for Firebase Error: Forbidden

I am trying to send multipart/form-data through URLRequest on my app to Cloud Functions for Firebase. And to test if my cloud function and my app are connected, I created a test function and deployed it:
function test(data, callback) {
console.log("Test begin:");
console.log(data);
console.log("Test finish...");
callback(null, null);
}
exports.test = functions.https.onRequest((request, respond) => {
console.log("test called");
test(request.body.data, function(data, error) {
respond.json({
data: data,
error: error
});
});
});
However, after sending the URLRequest, nothing was printed on the console, and instead, I got a html as data. By opening the html, I get Error: Forbidden. Your client does not have permission to get URL / from this server. How can I fix this?
Thanks to #Doug Stevenson, the problem is that I used the wrong URL instead of the provided one. And the URL can be found on the console when you deploy your cloud function.
Cloud Functions has special ways of dealing with different types of input. It's documented here.
For multipart/form-data, you can access the content as request.rawBody.

Calling Google AppScript Web App from Cloud Functions for Firebase

I'm trying to get my Cloud Functions for Firebase to call a simple web app deployed using Google Apps Script. Can someone please point to any example or help figure out whats the reason for the error in my code below. Really appreciate your help.
--
I've created a simple webapp with Google Apps Script.
function doGet() {
return ContentService.createTextOutput('Hello world');
}
And I'm calling this using request-promise within my Firebase Cloud Function. I've tried to be as close to the Google Translate example given for Cloud Functions. However, I get the following error when the Cloud Function is invoked.
RequestError: Error: getaddrinfo ENOTFOUND script.google.com
script.google.com:443
Here is my Cloud Function code -
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const request = require('request-promise');
exports.makeUppercase =
functions.database.ref('/users/{userid}/logs/{logid}/mykey')
.onWrite(event => {
var url = `https://script.google.com/macros/s/.../exec`;
var retstr = request(url, {resolveWithFullResponse: true}).then(
response => {
if (response.statusCode === 200) {
const data = response.body;
return event.data.ref.parent.child('uppercase').set(data);
}
throw response.body;
});
});
Thanks in advance,
Regards
Rahul
I had the same issue and found this answer(https://stackoverflow.com/a/42775841).
Seems like calling Google Apps Script is considered external.

How Firebase Cloud functions handle HTTP post method?

I have created Firebase Cloud Functions app,
I created function with https.onRequest.
and get data with req.body but there is not data there.
Can Firebase Cloud Functions can handle HTTP POST method?
This is my sample code:-
var functions = require('firebase-functions');
exports.testPost = functions.https.onRequest((req, res) => {
console.log(req.body);
});
I tested by postman with POST method but didn't show result in Firebase log.
Functions built on Firebase can also use Express.js routers for handling GET/POST/PUT/DELETE, etc... is fully supported by Google, and is the recommended way to implement these types of functions.
More documentation can be found here:
https://firebase.google.com/docs/functions/http-events
Here's a working example built on Node.js
const functions = require('firebase-functions');
const express = require('express');
const cors = require('cors');
const app = express();
// Automatically allow cross-origin requests
app.use(cors({ origin: true }));
app.get('/hello', (req, res) => {
res.end("Received GET request!");
});
app.post('/hello', (req, res) => {
res.end("Received POST request!");
});
// Expose Express API as a single Cloud Function:
exports.widgets = functions.https.onRequest(app);
Then, run firebase deploy, and that should compile your code and create the new "widgets" function. Note: You can rename widgets to anything you want. Ultimately, it will generate a URL for calling the function.
I am planning to do the same thing. What I reckon the approach should be is to check the request.method in the function body. A probable approach can be:
if (request.method != "POST") {
respond.status(400).send("I am not happy");
return;
}
// handle the post request
Here's some reference to the details regarding what the request object holds: https://firebase.google.com/docs/functions/http-events
Firebase functions support GET, POST, PUT, DELETE, and OPTIONS method, and you can check what kind of methods that trigger your function.
// Check for POST request
if(request.method !== "POST"){
res.status(400).send('Please send a POST request');
return;
}
Then to get data from POST request (for example JSON type) will be in the header of your request.
const postData = request.body;
// for instance
const format = req.body.format;
// query string params
let format = req.query.format;
Maybe your project hasn't been setup to communicate with your firebase database. Try the following from your terminal:
npm install -g firebase-tools
Then inside your project folder, run the following and login using your credentials
firebase login
Then
firebase init functions
This will create a folder with index.js, package.json and node_modules
If you are using Postman correctly the rest of your code should work.

Parse Cloud - Manual Entry for Installation (Push Notifications)

I'm using the Javascript SDK and Appccelerator Titanium. The Javascript SDK doesn't have a function to save deviceToken's for enabling push. I've tried various methods but the one that should work (does not) is saving via a Cloud Function. What am I doing wrong?
Parse.Cloud.define("subscribeToPush", function(request, response) {
Parse.Cloud.useMasterKey();
var Installation = Parse.Object.extend("Installation");
var membership = new Installation();
membership.set("deviceType", request.params.os);
membership.set("deviceToken", request.params.deviceToken);
membership.set("channels", ["general"]);
membership.save(null,{
success:function(membership) {
response.success(membership);
},
error:function(error) {
response.error(error);
}
});
});
After running this function Cloud Log shows that it was created, yet, I don't see it in the data browser.
I2014-10-22T01:29:30.319Z] v51: Ran cloud function subscribeToPush for user rCzHEXY5hN with:
Input: {"deviceType":"ios","deviceToken":"xxxXXXxxx","channels":["general"]}
Result: {"deviceToken":"xxxXXXxxx","channels": "general"],"objectId":"KCWtpcwy4i","createdAt":"2014-10-22T01:29:30.383Z","updatedAt":"2014-10-22T01:29:30.383Z","__type":"Object","className":"Installation"}

Resources