Calling Google AppScript Web App from Cloud Functions for Firebase - 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.

Related

Firebase Functions unable to run HelloWorld example with Unity

I try to call the most basic https function from unity, but I always get an internal error.
I deployed the function and it works when called by the browser:
https://us-central1-infinite-space-rpg.cloudfunctions.net/helloWorld
Node.js code:
const functions = require("firebase-functions");
exports.helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", {structuredData: true});
response.send("Hello from Firebase!");
});
unity code:
FirebaseFunctions functions = FirebaseFunctions.DefaultInstance;
var func = functions.GetHttpsCallable("helloWorld");
func.CallAsync().ContinueWithOnMainThread((response) =>
{
Debug.Log("result: " + response.Result.Data.ToString());
});
This is the faulted error response I get:
In the firebase dashboard I can see that the function gets called and it also completes without an error.
So the setup should be fine, but the "one or more errors occurred(INTERNAL) does not give any hint on what might be the issue.
Permissions should also be fine, all users can invoke the function.
I really hope that someone has an idea!
also tried the exact sample from firebase with the same error.
https://firebase.google.com/docs/functions/get-started
I`m now stuck with this since 2 days, is there a better place to ask such a specific question, maybe a firebase support forum?

Firebase Functions Accessing Firestore error: Could not load the default credentials

I've been attempting to get to the bottom of issues with a Firebase function I'm using to update some aggregate data in Firestore. I set up a simple test bed and found that any attempt to access the data triggers the error:
> Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
> at GoogleAuth.getApplicationDefaultAsync (/Users/michael/Documents/htdocs/vue/mjf20/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:160:19)
I've attempted to just copy the entire Firebase config into the initializeApp() function, but it still generates the same error. Here's the entire test code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
exports.postCache = functions.https.onRequest((request, response) => {
console.log("Starting test function");
db.collection('myCollection').doc('myDoc').get()
.then(snap => {
if (!snap.exists) {
console.log('Document not found');
} else {
console.log(snap.data());
response.send(snap.data());
}
})
.catch(error => {
console.log('In catch block');
console.log(error);
response.send(error);
});
});
If I take out the db stuff, the function will work fine. As soon as I add even the simplest firestore request, it generates the error. I've seen this issue asked about before, but the situations seem different, and none of the solutions seems to work. I'm stumped.
The code is perfectly fine.
I have implemented it exactly on my testing project using this tutorial.
I have added your code to index.js and in my firestore I have added collection myCollection with myDoc with just one testing field and deployed using firebase deploy.
Everything works fine. You should focus on your environment and deployment steps to figure out what is the problem. This link that you have in the error is mentioning environment variables. Maybe a case as well.
I hope it will help!

Dialogflow fullfilment on firebase function if ask from telegram

I wrote function which work on firebase function and which take an answer on request if request come from the dialog console or the Google Assistant emulator. But if I ask from Telegram this function doesn't work.
Answer like Say that one more time? or if I filled the form Responses on web I have this response.
How connect firebase function with Telegram?
'use strict';
const {
dialogflow,
Permission,
Suggestions,
BasicCard,
} = require('actions-on-google');
const firebase = require('firebase');
const functions = require('firebase-functions');
const app = dialogflow({debug: true});
app.intent('simple word', (conv) => {
conv.ask(`it's ok`);
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
The problems is that you're using the actions-on-google library, which is specifically designed to send results to the Assistant.
If you want to be able to send results to Telegram, you need to use the dialogflow-fulfillment library, which handles things slightly differently.

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.

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.

Resources