This question already has an answer here:
Firebase Cloud Functions throws a DNS error when calling an external API [duplicate]
(1 answer)
Closed 4 years ago.
I have been assigned on a task to fetch all tweets from a certain hashtag and send that data to my application. So I decided to use firebase cloud functions, I generated the key needed for the twitter api. I also tested get my homepage using postman status and worked, however my issue now when I test my code on good cloud functions I cant get it to work and the error message when I try this end point:
Error: could not handle the request
https://us-central1-don.cloudfunctions.net/api/
or
https://us-central1-don.cloudfunctions.net/api/statuses/user_timeline
and this is my code on firebase cloud functions
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const Twitter = require('twitter');
admin.initializeApp(functions.config().firebase);
const client = new Twitter({
consumer_key: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
consumer_secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
access_token_key: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
access_token_secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
});
const app = express();
/* Express */
app.get('/', function(req,res){
client.get('statuses/user_timeline', {screen_name: 'nodejs', count: 5}, function (error, tweets, response) {
if (!error) {
response.send({ title: 'Express', tweets: tweets })
}
else {
response.send({ error: "this is error: " + error })
}
});
});
// Cloud Function
exports.api = functions.https.onRequest(app)
Hope anyone can suggest any solutions, thanks.
Update: here is my function console where it also throws an error:
api Function execution took 8 ms, finished with status code: 404
api Billing account not configured. External network is not accessible
and quotas are severely limited. Configure billing account to remove
these restrictions
As mentioned in the comments, you should upgrade to a paid plan, you may find this other Stack Overflow question useful : Cloud Functions for Firebase - Billing account not configured
Hope this helps!
Related
I want to reset a specific value in my Firebase Realtime Database every day at 12:00 AM. To do this, I'm using the Firebase Admin SDK to change the data in Firebase Realtime Database and Cloud Functions to trigger the change at 12:00 AM every day.
This is an example structure of my Firebase Realtime Database:
{
"users": {
"fa54487d9cbb4214b00db80e2118e4e6": {
"daily": 10
}
}
}
This is the code in my index.js:
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
var functions = require('firebase-functions');
// The Firebase Admin SDK to access Cloud Firestore.
var admin = require('firebase-admin');
// Fetch the service account key JSON file contents
var serviceAccount = require("serviceAccountKey.json");
// Initialize the app with a service account, granting admin privileges
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://databaseName.firebaseio.com"
});
// As an admin, the app has access to read and write all data, regardless of Security Rules
var db = admin.database();
var ref = db.ref("users");
// Reset today GHG emissions at 12:00 AM everyday
exports.dailyReset = functions.pubsub.schedule('0 0 * * *').onRun((context) => {
usersRef.child("{userId}").set({
daily: 0
});
});
Deploy Error:
! functions[dailyReset(us-central1)]: Deployment error.
Function failed on loading user code. This is likely due to a bug in the user code. Error message: Error: please examine your function logs to see the error cause: https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs. Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging. Please visit https://cloud.google.com/functions/docs/troubleshooting for in-depth troubleshooting documentation.
Firebase Console Functions Logs:
Error: function terminated. Recommended action: inspect logs for termination reason.
Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging Function cannot be initialized.
{"#type":"type.googleapis.com/google.cloud.audit.AuditLog","status":{"code":3,"message":"Function failed on loading user code. This is likely due to a bug in the user code.
Error message: Error: please examine your function logs to see the error cause: https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs.
Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging.
The script won't deploy when I use firebase deploy as my function is giving me an error. Can someone tell me how to fix my code?
This won't work:
exports.dailyReset = functions.pubsub.schedule('0 0 * * *').onRun((context) => {
usersRef.child("{userId}").set({
daily: 0
});
});
There is nothing here that interprets the {userId} in that path, so the database updates the literal path "/users/{userId}", which is not what you want.
If you know what user ID you want to update, you should use that value in the path:
exports.dailyReset = functions.pubsub.schedule('0 0 * * *').onRun((context) => {
let usersRef = admin.database().ref("users");
usersRef.child("theActualUserIdYouWantToUpdate").set({
daily: 0
});
});
If you don't know what user ID to update, you'll need to query the database to determine that.
If you want to loop over all users, you can do:
exports.dailyReset = functions.pubsub.schedule('0 0 * * *').onRun((context) => {
return usersRef.once("value").then((snapshot) => {
let updates = {};
snapshot.forEach((userSnapshot) => {
updates[userSnapshot.key+"/daily"] = 0
});
return usersRef.update(updates);
});
});
If you are new to JavaScript or interacting with the Realtime Database in it, Cloud Functions for Firebase is not the best way to learn it. I recommend first reading the Firebase documentation for Web developers and/or taking the Firebase codelab for Web developer. They cover many basic JavaScript, Web and Firebase interactions. You could also use the Admin SDK in a local Node.js process, which can be debugged with a local debugger. After those you'll be much better equipped to write code for Cloud Functions too.
Stripe version: "8.107.0"
I keep getting a Stripe webhook verification error whenever I run my webhook on GCP. I've tried using the raw body in the signature, as the code snippet below mentions, as well as other ways to pass the req.rawBody as other StackOverflow answers mention.
The weird thing is that this error seems to be thrown when I deploy to GCP, and not when I run locally. I tried to manually create the signature (https://stripe.com/docs/webhooks/signatures#verify-manually), and the same result there: locally the signatures match, on GCP it doesn't.
Our server is hosted on GCP GKE, and we serve requests to our server through an Nginx Reverse Proxy. Other stack overflow solutions mentioned Google Cloud Functions and Lambda. As far as I'm aware, we do not parse requests on GCP
I do use bodyParser.json(), but that's setup after this endpoint. These are the ways I've tried creating / using a rawBody:
app.use(express.json({verify: (req,res,buf) => { req.rawBody = buf }}));
bodyParser.json({
verify: (req: any, res, buf) => {
req.rawBody = buf.toString();
},
}),
event = stripe.webhooks.constructEvent(req.rawBody, sig, webhookSecret);
I based my code on the stripe example found here: https://github.com/stripe/stripe-node/blob/master/examples/webhook-signing/node-express/express.js
// Stripe requires the raw body to construct the event
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
} catch (err) {
// On error, log and return the error message
console.log(`❌ Error message: ${err.message}`);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
// Successfully constructed event
console.log('✅ Success:', event.id);
// Return a response to acknowledge receipt of the event
res.json({received: true});
});
Any help would be appreciated, thanks.
The issue was with one of our setup files, where basically a space or an \n character was getting added to our webhookSecret
We had the same problem here, and it was fixed by looking for a development webhook secret (as we have a different url for development environment - it is a different webhook secret - consider look that when you have this problem).
I'm trying to integrate Twilio into a triggered Firestore function. The problem I'm having is when I add this code, I am unable to deploy ANY functions. As far as I know this is how to use twilio inside a cloud function. At the top I have this and I think firebase doesn't like something here because ALL functions stop deploying with this code.
// Used to send text messages
const twilio = require('twilio')
// const accountSid = functions.config().twilio.sid
// const authToken = functions.config().twilio.token
/* eslint new-cap: ["error", { "newIsCap": false }] */
const client = new twilio('ACblahblahblah', 'ccblahblahblah') // sid and token
const twilioNumber = '+13344714571' // your twilio phone number
Within the triggered function I have this. But I don't think the issue is here:
return client.messages.create({
to: someNumber,
from: twilioNumber,
body: 'Some message.'
}).then((data) => {
console.log(data)
}).catch((error) => {
console.log(error)
})
I have a valid Twilio account set up. The function logs don't tell me much other than that the function cannot be initialized. What am I missing? Seems like this has worked for others.
Figured it out about 5 minutes after posting the question. I had not installed twilio in the functions folder but rather the root of the project. Once I executed
npm install twilio
in the functions folder, the functions started deploying. Too bad there was no error in the logs that said something like "required package is missing" or something like that.
ok so I set up an Ionic webapp with a contact form and I have the form interacting with firebase meaning all my form info is being stored on the real time database. Now I have setup SendGrid according to this tutorial:
Firestore - Database Triggered Events;
https://fireship.io/lessons/sendgrid-transactional-email-guide/
However the cloud functions are not being triggered when new data is being entered. I am not getting any errors on the console and from sendgrid dashboard there are no requests. My understanding is that when there is change in the database it will automatically trigger the function and then sendgrid will send emails with the relevant data.
Here is my code;
// Firebase Config
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
// Sendgrid Config
import * as sgMail from '#sendgrid/mail';
const API_KEY = functions.config().sendgrid.key;
const TEMPLATE_ID = functions.config().sendgrid.template;
sgMail.setApiKey(API_KEY);
// Emails the author when a new messages is added
export const newMessage = functions.firestore.document('messages/{messageId}').onCreate( async (change, context) => {
// Raw Data
// const post = postSnap.data();
const msgData = change.data();
// Email
const msg = {
to: msgData.email,
from: 'Your_email#gmail.com',
templateId: TEMPLATE_ID,
dynamic_template_data: {
subject: 'New Message',
name: msgData.name,
text: `Here is the message: ${msgData.message}`,
phone: msgData.phone
},
};
// Send it
return sgMail.send(msg);
});
Deployment of the functions was successful to firebase.
Please any help is appreciated.
edit //////////////////////////////////////////////// edit
Ended up using Nodemailer instead.
It's Probobly Free Firebase Spark Plan https://firebase.google.com/pricing. Cloud Functions: Outbound Networking = Google Services Only. If You change to Blaze Plan You still will not pay any thing if You no use much Outbound Networking. I have 2x Blaze Plans 3 months and pay nothing.
ok so this is what worked for me after searching and searching. Thanks to #Mises for giving me a direction to follow. For others that are trying to send transactional emails with firebase using nodemailer here is how I did it.
I followed the above link given to me by #Mises;
https://github.com/firebase/functions-samples/tree/Node-8/email-confirmation
I was able to upload the function to firebase, but I was still getting an error in firebase function logs;
-There was an error while sending the email: { Error: Missing
credentials for "PLAIN"
So then from there I followed this link;
Missing credentials for "PLAIN" nodemailer
unfortunately activating less secure apps on google did not work for me.
aslo offical docs from nodemailer here;
https://nodemailer.com/about/
Hope this helps someone else.
I am getting an error stating external network is not accessible, which makes sense as I am on the free tier of Firebase. But I thought Firebase services were included in the free tier, and as such, I should be able to use FCM.
Here is the code I am using for my index.js for the functions.
var functions = require('firebase-functions');
var admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
exports.buttonPress = functions.https.onRequest((req, res) => {
let testToken = "TOKEN";
let payload = {
data: {
type: req.body.type
}
};
admin.messaging().sendToDevice(testToken, payload)
.then(function (response) {
...
})
.catch(function (error) {
...
});
});
firebaser here
Billing account not configured. External network is not accessible and quotas are severily limited. Configure billing account to remove these restrictions.
This message now shows up for any Cloud Functions that are invoked from projects that are on the free tier. It doesn't mean that any calls have actively been blocked, just they calls to external services will be blocked for this project.
We're looking if we can get the message removed.
For Free tier account, Firebase has imposed a restriction on accessing external service that is not within google's network.
To get to the root cause of the problem just go to the Firebase console and check your functions's log. The log will show exactly what service or packages you installed is trying to make external HTTP request.
To sent FCM through cloud functions, you can use the code below.
Check log if you are getting right tokens.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendNotification = functions.firestore
.document('/users/{documentId}')
.onWrite((change, context) => {
console.log("DOCUMENT ID : " + context.params.documentId);
//Get all data
const payload = {
notification: {
title: 'Test title!',
body: `${userName} sent you a following request.`
// icon: follower.photoURL
}
};
admin.messaging().sendToDevice(followedFCMToken, payload)
.then(function (response) {
console.log("Push response : " + response);
return response
})
.catch(function (error) {
console.error("Error in sending push");
});
});