Send a POST request by axios with firebase functions - javascript

I am trying to send a POST request via axios andfirebase cloud function while the body of the request in axios contains data from changes occured in realtime db using the functions but everytime I deploy my code I get the 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.
I am quite new to firebase functions so I really don't know what I am doing here even after having some research.
Code:
const functions = require("firebase-functions");
const axios = require("axios");
exports.newNodeDetected = functions.database
.ref("Orders/{userId}/{customerId}/{ordernum}/customername")
.onCreate((snapchot, context) => {
const order = snapchot.val();
const userId = context.params.userId;
console.log(userId + "AND CUS NAME IS" + order);
axios.post("http://something.com/data.php", {
username: userId,
title: "ttl",
message: "msg",
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
});

Just in case anyone had the same issue. I realized I was running my npm commands outside the functions folder, therefore the package.json wasn't getting edited and my libraries were not really getting downloaded.
Always be careful to use npm inside the functions folder!!

Related

Firestore function deployment error when using Twilio

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.

Firebase Callable Cloud Function CORS Error

The following is the client side code to call the cloud function:
var getShippingRate = firebase
.functions()
.httpsCallable("shippo-generateShippingRate");
getShippingRate({ address: shippo })
.then(function(result) {
// Read result of the Cloud Function.
console.log("THE SHIPPING RATES", result.data.shipment);
})
.catch(function(error) {
// Getting the Error details.
console.log("ERROR SHIPPING: ", error);
var code = error.code;
var message = error.message;
var details = error.details;
});
The cloud function:
exports.generateShippingRate = functions.https.onCall(async (data, context) => {
const customer_address = data.address;
return generateShipmentObject(customer_address);
});
generateshipmentObject returns this:
shippo.shipment.create(
{
address_from: addressFrom,
address_to: addressTo,
parcels: [parcel],
async: true
},
(err, shipment) => {
// asynchronously called
if (err) {
return { error: err };
} else {
return { result: shipment };
}
}
I get the standard CORS Error, but a callable Cloud Function should handle this automatically:
Access to fetch at ... from origin 'http://localhost:5000' has been blocked by CORS policy:
EDIT
I'm using firebase serve --only hosting to test on localhost.
The Cloud Functions are deployed with firebase deploy --only funtions
I'm calling other similar Cloud Functions on the same site which do not have that issue.
Temp fix:
In the cloud console functions page, select a function to show the info panel. In the permissions tab, select ADD MEMBER. In the new members field, type allUsers. In the roles drop down, select cloud functions, then cloud functions invoker, and save.
It actually sort of makes sense for a function to have restricted permissions when it's first created, however I'm used to the default permissions being present, so it's a bug (or new feature) that definitely threw me off. Of course this doesn't fix the underlying problem, but hope it helps.

Add Mailchimp susbscriber through Firebase Function

Scenario :
I'm trying to create a Firebase Function to add a subscriber to a Mailchimp list using the Mailchimp API but after three days of trying different methods I've had little luck.
Currently my function resembles:
exports.addSubscriber = functions.https.onRequest((req, res) => {
const Mailchimp = require('mailchimp-api-v3')
const mailchimp = new Mailchimp('MY_API_KEY');
mailchimp.post('/lists/'MY_LIST_ID'/members', {
"email_address": 'test#gmail.com',
"status": 'pending'
}).then(function(results) {
console.log('added new user to mailchimp list');
})
.catch(function(err) {
console.log(err);
})
return null
});
When I try to trigger the function it results in a 'crash' with Error: Cannot find module 'mailchimp-api-v3' in the logs.
I've already ran npm install mailchimp-api-v3 in my local Firebase
directory so the module should be available.
Where am I going wrong?
Is there a simpler way to use the Mailchimp API with Javascript?
Try to run
npm install mailchimp-api-v3 --save
It seams the above package is missing.

How to log the AWS Amplify API.get request to view queryStringParameters on url

I'm not sure how to log / see the actual request that is being made.
I can look at this code below and assume that it's http://myendpoint.com?my/path?param=value, however with more complex code and variables in other places, how can I tell what exactly is getting called via API.get?
The main reason I ask is because I don't think my query parameters are being appended to my request, and I'm hoping to confirm.
const apiName = 'http://myendpoint.com'
const path = '/my/path'
const myInit = {
queryStringParameters: {
param: 'value'
}
}
API.get(apiName, path, myInit)
.then((response) => {
console.log('> > > PLEASE TELL ME HOW TO LOG THE REQUEST < < <')
resolve(response)
},
(err) => {
console.log('err resp', err)
resolve(err)
})
Edit: FYI this is in a REACT NATIVE project, so things like the Chrome Network tab are of no use unfortunately.
Okay, I actually think I figured this out, and it boiled down to two different things:
1. ADDING THE AMPLIFY LOGGER:
I found there is an Amplify logger via:
https://github.com/aws/aws-amplify/blob/master/media/logger_guide.md
So I added:
Amplify.Logger.LOG_LEVEL = 'DEBUG'
and now when I am debugging in VS Code I'm seeing the request URL being logged.
2. REALIZING 'queryStringParameters' ISN'T ACTUALLY SUPPORTED: .
I was looking through the Amplify GitHub repo issues and found out that queryStringParameters isn't actually supported yet, which is fun.
URL to issue: https://github.com/aws/aws-amplify/issues/127 .
So instead I appended all my query parameters onto the path, and that works:
const apiName = 'http://myendpoint.com'
const path = `/my/path?param=${value}`
API.get(apiName, path)
.then((response) => {
resolve(response)
},
(err) => {
console.log('err resp', err)
resolve(err)
})
I am now seeing the request URL logged, and seeing the parameters as a part of the request.

CF Connect to the cloud controller

I use the following lib to connect to the cloud controller
https://github.com/prosociallearnEU/cf-nodejs-client
const endpoint = "https://api.mycompany.com/";
const username = "myuser";
const password = "mypass";
const CloudController = new (require("cf-client")).CloudController(endpoint);
const UsersUAA = new (require("cf-client")).UsersUAA;
const Apps = new (require("cf-client")).Apps(endpoint);
CloudController.getInfo().then((result) => {
UsersUAA.setEndPoint(result.authorization_endpoint);
return UsersUAA.login(username, password);
}).then((result) => {
Apps.setToken(result);
return Apps.getApps();
}).then((result) => {
console.log(result);
}).catch((reason) => {
console.error("Error: " + reason);
});
I try to run it against our API and its not working and Im not getting no error message in the console, what it can be ?
where does the space/org is handled here ? since when I connect from the cli it ask me to which space/org I want to connect...
Im able to login via the CLI, just from the code I cant, any idea what is missing here?
The issue it when I run it I dont get any error that can help to understand what is the root cause
I cloned the original git repository and modified some methods to support proxy. Please note that I modified just some methods to get the sample code working, but a complete refactor of the package is needed.
Basically what you have to do is to add a proxy parameter before calling the request method (this is done throughout the package, so several modifications are needed), for example this is for one of the methods in the Organization.js file:
getSummary (guid) {
const url = `${this.API_URL}/v2/organizations/${guid}/summary`;
const proxy = `${this.API_PROXY}`;
const options = {
method: "GET",
url: url,
proxy: proxy,
headers: {
Authorization: `${this.UAA_TOKEN.token_type} ${this.UAA_TOKEN.access_token}`
}
};
return this.REST.request(options, this.HttpStatus.OK, true);
}
You can find my changes in the git repository below:
https://github.com/adasilva70/cf-nodejs-client.git
I have also created a new sample below. This sample lists all organizations for a user, gets the first organization returned and lists its spaces. You can modify the code to provide a similar functionality that cf login provides (allow you to select an organization then a space).
const endpoint = "https://api.mycompany.com/";
const username = "youruser";
const password = "yourpassword";
const proxy = "http://proxy.mycompany.com:8080";
const CloudController = new (require("cf-nodejs-client")).CloudController(endpoint, proxy);
const UsersUAA = new (require("cf-nodejs-client")).UsersUAA;
const Apps = new (require("cf-nodejs-client")).Apps(endpoint, proxy);
const Orgs = new (require("cf-nodejs-client")).Organizations(endpoint, proxy);
CloudController.getInfo().then((result) => {
console.log(result);
UsersUAA.setEndPoint(result.authorization_endpoint, proxy);
return UsersUAA.login(username, password);
}).then((result) => {
//Apps.setToken(result);
//return Apps.getApps();
Orgs.setToken(result);
return Orgs.getOrganizations();
}).then((result) => {
console.log(result);
org_guid = result.resources[1].metadata.guid;
return Orgs.getSummary(org_guid);
}).then((result) => {
console.log(result);
}).catch((reason) => {
console.error("Error: " + reason);
});
I have done just minor tests to make sure the sample works, so use carefully. Also, the changes will only work for a case where proxy is needed now.
The first thing that strikes me on the library's github site is the warning:
Note: This package is not ready for a production App yet.
It also seems that the project is not being maintained as there are a number of tickets ooened that are quite a few months old that don't have a response.
Anyway, to figure out why the library is not working and producing no error message, I would check out the library source code and add some console logging statements, probably starting with the HttpUtils. For example:
requestWithDefaults(options, function (error, response, body) {
console.log("requestWithDefaults error: ", error)
console.log("requestWithDefaults response: ", response)
console.log("requestWithDefaults body: ", body)
...
}
Alternatively, you could try debugging the code by adding breakpoints to the requestWithDefaults and other key places in the library, using the nodejs debugger.
You could also try debugging the network calls similar to this how to monitor the network on node.js similar to chrome/firefox developer tools?
To understand how to use the library, I would take a look into the tests folder and look for a test that is similar to your use case. There are a reasonable amount if tests that look useful in the test/lib/model/cloudcontroller folder.
As for the question about spaces, I have found an example where you can pass in a space guid to return apps for that space guid.
CloudFoundrySpaces.getSpaceApps(space_guid, filter).then( ... )
I'm assuming the call you are using App.getApps() will return Apps for all spaces/organizations.

Categories

Resources