I want to use Stripe with Firebase Functions.
Attempting to deploy the following source code to functions will result in an error.
const functions = require('firebase-functions');
const express = require("express");
const app = express();
// This is your real test secret API key.
const stripe = require("stripe")("STRIPE KEY HERE");
app.use(express.static("."));
app.use(express.json());
const calculateOrderAmount = items => {
// Replace this constant with a calculation of the order's amount
// Calculate the order total on the server to prevent
// people from directly manipulating the amount on the client
return 1400;
};
app.post("/create-payment-intent", async (req, res) => {
const { items } = req.body;
// Create a PaymentIntent with the order amount and currency
const paymentIntent = await stripe.paymentIntents.create({
amount: calculateOrderAmount(items),
currency: "usd"
});
res.send({
clientSecret: paymentIntent.client_secret
});
});
module.exports.express = functions.https.onRequest(app);
This is what I want to achieve.
https://stripe.com/docs/payments/integration-builder
I want to deploy to Firebase Functions using react for the front and Node for the back end.
</functions/package.json>
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "12"
},
"main": "index.js",
"dependencies": {
"firebase-admin": "^9.2.0",
"firebase-functions": "^3.11.0"
},
"devDependencies": {
"eslint": "^7.6.0",
"eslint-config-google": "^0.14.0",
"firebase-functions-test": "^0.2.0"
},
"private": true
}
When I tried the command "firebase deploy --only" functions: express ", I got the following error:
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
This was accompanied by this Log object:
{
"#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. Please visit https://cloud.google.com/functions/docs/troubleshooting for in-depth troubleshooting documentation."
},
"authenticationInfo": {
"principalEmail": "MYADDRESS#gmail.com"
},
"serviceName": "cloudfunctions.googleapis.com",
"methodName": "google.cloud.functions.v1.CloudFunctionsService.UpdateFunction",
"resourceName": "projects/MYPROJECT/locations/us-central1/functions/express"
}
i deploying functions
i functions: ensuring required API cloudfunctions.googleapis.com is enabled ...
i functions: ensuring required API cloudbuild.googleapis.com is enabled ...
✔ functions: required API cloudbuild.googleapis.com is enabled
✔ functions: required API cloudfunctions.googleapis.com is enabled
i functions: preparing functions directory for uploading ...
i functions: packaged functions (44.09 KB) for uploading
✔ functions: functions folder uploaded successfully
i functions: creating Node.js 12 function express (us-central1) ...
Functions deploy had errors with the following functions:
express (us-central1)
To try redeploying those functions, run:
firebase deploy --only "functions: express"
To continue deploying other features (such as database), run:
firebase deploy --except functions
Error: Functions did not deploy properly.
Does anyone know the solution?
You need to export the Express.js app as an HTTPS function with
exports.app = functions.https.onRequest(app);
instead of doing
module.exports.express = functions.https.onRequest(app);
See the doc.
Then you need to deploy with, for example, firebase deploy --only functions.
Note that it seems that there is an extra double quote (") in the command you entered:
I typed the command "firebase deploy --only" functions: express "
Related
This question already has answers here:
Error Deploying Firestore Function with a space in the name of a collection
(2 answers)
Closed 2 years ago.
I have been trying to deploy my firebase function called onFollowUser however, it has been constantly failing to launch. I have the Blaze plan currently and this is the error message:
⚠ functions[onFollowUser(us-central1)]: Deployment error.
Failed to configure trigger providers/cloud.firestore/eventTypes/document.create#firestore.googleapis.com (__gcf__.us-central1.onFollowUser)
Functions deploy had errors with the following functions:
onFollowUser
To try redeploying those functions, run:
firebase deploy --only functions:onFollowUser
To continue deploying other features (such as database), run:
firebase deploy --except functions
Error: Functions did not deploy properly.
Here is my complete index.js:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.onFollowUser =
functions
.firestore
.document('/Followers/{userID}/User Follower/{followerID}')
.onCreate(async (snapshot, context) => {
console.log(snapshot.data());
});
I have spotted the error... My database is located in Europe-central, however, for some reason, it is deploying to US-central... How can I change this? The ID of my project which it says it is deploying to is correct.
Here is my package.json:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "10"
},
"dependencies": {
"firebase-admin": "^8.10.0",
"firebase-functions": "^3.6.1"
},
"devDependencies": {
"eslint": "^5.12.0",
"eslint-plugin-promise": "^4.0.1",
"firebase-functions-test": "^0.2.0"
},
"private": true
}
Edit: Even though I get this failing message, I can see the function on my console :
This is a know issue, see: Error Deploying Firestore Function with a space in the name of a collection
Rename the a collections so that they do not includes spaces, rather use camel case, dashes or underscores.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
admin.firestore().settings({ timestampsInSnapshots: true });
exports.onFollowUser =
functions
.firestore
.document('/Followers/{userID}/User-Follower/{followerID}')
.onCreate(async (snapshot, context) => {
console.log(snapshot.data());
return;
});
When trying to use the cloud functions emulator, I get a message stating:
function ignored because the firestore emulator does not exist or is not running
I have tried mentioned here: (Firestore/Firebase Emulator Not Running).
My functions/package.json looks like this:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"dependencies": {
"firebase-admin": "^8.0.0",
"firebase-functions": "^3.1.0"
},
"devDependencies": {
"eslint": "^5.12.0",
"eslint-plugin-promise": "^4.0.1",
"firebase-functions-test": "^0.1.6"
},
"private": true
}
Command I'm using to start the emulator:
firebase emulators:start --only functions
This is the output I'm getting:
i Starting emulators: ["functions"]
! Your requested "node" version "8" doesn't match your global version "10"
+ functions: Emulator started at http://localhost:5001
i functions: Watching "C:\Users\MyName\Documents\MyProject\functions" for Cloud Functions...
i functions[updateFunction]: function ignored because the firestore emulator does not exist or is not running.
+ All emulators started, it is now safe to connect.
I am doing a console.log in the function but I don't see it on the port (5001).
Any help would be appreciated.
If you want to trigger a Firestore function, you will need to make that change in the local Firestore emulator. Locally emulated functions don't respond to actual cloud-hosted databases. The emulation on all products must be local.
functions[updateFunction]: function ignored because the firestore emulator does not exist or is not running.
Maybe the 'updateFunction' is the handler function for watching a change of your firestore documents, isn't it?
So you might need to start firestore at the same time with functions.
Just execute without --only option with the firebase.json configurations
{
"hosting": {
"public": "public",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
},
"functions": {
"source": "functions"
},
"emulators": {
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"hosting": {
"port": 5000
},
"ui": {
"enabled": true,
"host": "localhost",
"port": 4000
}
}
}
And if you want to connect your server-side functions with your IDE for debugging, you need '--inspect-functions' option, or you just have to check logs in the emulator log page "http://localhost:4000/logs"
firebase emulators:start --inspect-functions
I've been trying callable functions to avoid handling cors manually but so far nothing is working
i've read similar issue Firebase Callable Function + CORS
the difference is the that dude has 'no access control allow origin' issue. Mine is response to preflight ... issue
I'd like to request for a guidance people. It's frustrating argh..
I'm on Blaze plan
So far i've been trying only to run the functions Locally. i have not deployed the function at all.
this is my function code
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.createOrder = functions.https.onCall((data, context) => {
return new Promise((resolve, reject) => {
resolve(data)
.then(result => {
return result;
})
.catch(err => {
console.error(err.code);
throw new functions.https.HttpsError('unknown', err.message);
});
});
});
this is my client code
export const createOrder = order => {
functions
.httpsCallable('createOrder')({ data: order })
.then(result => {
console.log('result create order is', result);
return result;
});
};
functions package.json
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"dependencies": {
"#sendgrid/mail": "^6.4.0",
"axios": "^0.19.0",
"cors": "^2.8.5",
"firebase": "^6.3.1",
"firebase-admin": "^8.2.0",
"firebase-functions": "^3.1.0",
"firebase-functions-test": "^0.1.6"
},
"engines": {
"node": "8"
},
"private": true
}
firebase config.json
"firebase": {
"apiKey": "AIzaSy*****",
"authDomain": "jokii-test.firebaseapp.com",
"databaseURL": "https://jokii-test.firebaseio.com",
"projectId": "jokii-test",
"storageBucket": "jokii-test.appspot.com",
"messagingSenderId": "104544.....",
"appId": "1:10454485....."
}
Firebase SDK = "firebase": "^6.3.1",
The client SDK doesn't know how to access a function that hasn't been deployed. Notice in the error output that the URL it's trying to access is the one for your fully deployed function. It's currently not possible to have it override the URL to access one you're running locally on localhost.
If you want to invoke your callable function locally, you'll need to implement a client that follows the protocol specification for callable functions. And, as you can see, that's going to be a fair amount of work, because the client SDK is managing a lot of the HTTP protocol work for you.
I'm just trying to fetch "uid" of my authenticated users using firebase functions. But every time I run the function in "firebase functions:shell". I get these errors. can anyone help me fix this problem?
"context.auth.uid" TypeError: Cannot read property 'uid' of undefined
exports.sendNewUser = functions.database.ref('/Users/')
.onCreate(async (snapshot, context) => {
const userId = await context.auth.uid;
const tokenPath = await admin.database().ref('Notify').once('value')
var message = []
tokenPath.forEach((childSnapshot) => {
var allTokens = childSnapshot.val().expo
if (allTokens) {
message.push({
"to": allTokens,
"header": " Users",
"body": "New user has been added, check them out!!!"
})
}
})
await fetch('https://exp.host/--/api/v2/push/send', {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(message)
})
console.log("The user ID is : " + userId)
})
Package.json:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"dependencies": {
"dateformat": "^3.0.3",
"firebase-admin": "6.3.0",
"firebase-functions": "^2.1.0",
"node-fetch": "^2.3.0"
},
"devDependencies": {
"eslint": "^4.12.0",
"eslint-plugin-promise": "^3.6.0"
},
"private": true
}
The context.auth.uid will be undefined with the onCreate trigger, as this is triggered by the cloud funtions runtime and not the user that created the document.
See https://stackoverflow.com/a/64345666/4868790
The documentation for running Realtime Database triggers is clear:
By default, the shell runs Realtime Database functions with
administrative privileges. Use the auth option to instead run
functions as a particular end user, or as an unauthenticated user:
# to mock unauthenticated user
myDatabaseFunction('data', {authMode: 'USER'})
# to mock end user
myDatabaseFunction('data', {auth: {uid: 'abcd'}})
You need to pass the last object that simulates the auth payload in the context. Without that, auth will contain nothing.
It will work fine when you publish it.
You don't need to use await when accessing the uid. It's not an asynchronous function.
I'm following the example from the github repository to short a link url
https://github.com/firebase/functions-samples/tree/Node-8/url-shortener
The error is giving is the following
12:49:56.472 a. m. shortenUrl Function execution took 509 ms, finished
with status: 'error' 12:49:56.464 a. m. shortenUrl RequestError:
Error: getaddrinfo EAI_AGAIN api-ssl.bitly.com:443
at new RequestError (/srv/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/srv/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/srv/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/srv/node_modules/request/request.js:185:22)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at Request.onRequestError (/srv/node_modules/request/request.js:881:8)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at TLSSocket.socketErrorListener (_http_client.js:387:9)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickDomainCallback (internal/process/next_tick.js:218:9)
I'm really new at functions but I did follow all the steps from the documentation there.
here is my index.js inside my functions folder
const functions = require('firebase-functions');
const BitlyClient = require('bitly');
// TODO: Make sure to set the bitly.access_token cloud functions config using the CLI.
const bitly = BitlyClient(functions.config().bitly.access_token);
// Shorten URL written to /links/{linkID}.
exports.shortenUrl = functions.database.ref('/links/{linkID}').onCreate(async (snap) => {
const originalUrl = snap.val();
const response = await bitly.shorten(originalUrl);
return snap.ref.set({
original: originalUrl,
short: response.data.url,
})
});
and my package.json in order to compile the the neccesary for bitly
{
"name": "url-shortener-functions",
"description": "URL Shortener Firebase Functions sample",
"dependencies": {
"bitly": "^5.1.7",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.0.5"
},
"devDependencies": {
"eslint": "^4.13.1",
"eslint-plugin-promise": "^3.6.0"
},
"scripts": {
"lint": "./node_modules/.bin/eslint --max-warnings=0 .",
"serve": "firebase serve --only functions",
"shell": "firebase experimental:functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"private": true
}
I also did npm -install bitly inside my functions folder but still throwing that error
Also I added my link inside my database as the documentation states
/functions-project-12345
/links
link-123456: "https://my.super.long-link.com/api/user/profile/-jEHitne10395-k3593085"
Any clue ? thanks
it complains, that it cannot resolve for the remote host:
RequestError: Error: getaddrinfo EAI_AGAIN api-ssl.bitly.com:443
therefore I'd assume, that a paid plan is required, in order to perform this external API call.