Nexmo: Receiving SMSes - firebase

As one new to Nexmo, I found an easy way to receive SMSes using Firebase here.
After initialising Firebase with:
firebase init functions
you write into the generated index.js:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.inboundSMS = functions.https.onRequest(async (req, res) => {
await admin.database().ref('/msgq').push(req.body);
res.send(200);
});
Then you deploy the code to Firebase with:
firebase deploy --only functions
which yields a callback URL (webhook) similar to:
https://us-central1-nexmo-project.cloudfunctions.net/inboundSMS
By adding the above URL in the API settings of the Nexmo Dashboard, the messages will be grabbed by Firebase DB.
Now I have two questions.
The first is a licencing problem: the author claims that the Firebase "Pay-as-you-go plan is required to use a third-party API". What does this mean? Isn't the webhook consumer always a third party? I don't find any useful hint on Firebase site.
The second question regards securing the callback URL. It seems that everyone can send data through the URL, so how can I avoid spamming and peruse of the URL?

Glad you found my post useful.
To answer your questions -
If you are using Nexmo to send an SMS, or any other service that would require you to call a 3rd party API, you would need to use the pay-as-you-go from Firebase. If you only want to use it as a webhook that would be called from an external source into Firebase, the free tier should be usable. The difference is in the calling external APIs. Google provides a better explanation of this type of call - https://firebase.google.com/docs/functions/use-cases#integrate_with_third-party_services_and_apis. Google network calls shouldn't be included in this - one of the benefits of using Firebase.
Securing the webhook has a couple of options. The first is, it's not an easily discoverable URL, so keeping it private should be the initial line of defense. Nexmo also has a list of IP's that can be whitelisted here - https://help.nexmo.com/hc/en-us/articles/204015053. In the headers you should be able to locate the IP and verify it before allowing it to do anything else, or just kick it out completely.
Let me know if that helps!

Related

How to Connect Google Play Real-Time Developer Notifications to Firebase Cloud Function via Pub/Sub?

I'm in the final stages of development for my new mobile app, but can't seem to find a way to allow Google Play Real-Time Developer Notifications to communicate to a firebase cloud function via the recommended Google Pub/Sub method.
The expected payload flow should go as follows:
User Purchases Subscription via Play Store > Play Store sends R-T Dev Notification to Pub/Sub > Pub/Sub sends message across to firebase cloud function > Cloud function runs with payload.
I currently have an Apple Developer webhook set-up in a similar way, which webhooks a receipt payload to an iOS cloud function I have setup.
During the pub/sub setup phase, the Pub/Sub page asks to verify the cloud function URL, which I cannot do as I am not the true webmaster of cloud function domain, hence halting me about halfway down the 'Add real-time developer notification' docs that google supplies.
Is there a way to get the RT notification to either a Pub/Sub cloud function or a HTTPS cloud function bypassing the google Pub/Sub and going directly to the webhook or another way to complete the flow above?
The ultimate aim is to provide a way to ensure the purchase made is actually a valid purchase, and not a forged request made by someone intercepting the client > server webhook and submitting one of their own accord.
After creating the new topic you DO NOT have to create manually a Pub/Sub subscription as explained in the documentation.
To make it work with firebase you have to deploy a new cloud function like this:
exports.YOUR_FUNCTION_NAME = functions.pubsub.topic('YOUR_TOPIC_NAME').onPublish((message) => {
// Decode the PubSub Message body.
const messageBody = message.data ? Buffer.from(message.data, 'base64').toString() : null;
// Print the message in the logs.
console.log(`Hello ${messageBody || 'World'}!`);
return null;
});
Please note that you need to replace YOUR_FUNCTION_NAME and YOUR_TOPIC_NAME.
When the deploy of this function finish, you will finally find the function in the subscription list.
At this point, you can edit the params of the automatically created subscription, and you will find the url endpoint already filled with an internal url.
Here you can find an example: how to setup a PubSub triggered Cloud Function using the Firebase SDK for Cloud Functions.

How to notify a Firebase Admin SDK user using a cloud function?

I am a student developing an app and I have some back-end python code that utilizes the Firebase admin SDK. The app with provide an interface to an proprietary algorithm that cannot be moved into the a cloud function and so must stay within the back-end server. When a user makes a request to the algorithm, they will do so by uploading a document to Firestore with information the back-end needs to process their request.
Once a user uploads a document, an onCreate() cloud function is triggered, the goal of this function is to simply notify the back-end that there is a pending request, so that it can process it and send back to the user.
This is where I am struggling, I haven't been able to deduce a way to trigger action on the back-end from within the cloud function. I am hoping to find a way to accomplish this through Firebase without the need to implement additional libraries etc.
A way to generalize my issue would be:
How would you notify an Firebase Admin SDK user through a Cloud Function?
FCM is used for sending messages and notifications to mobile clients. It doesn't work for sending messages to backend components.
If you want to notify some backend component, you typically use an HTTP endpoint or pubsub messaging.
Firebase Functions SDK already uses the Firebase Admin SDK under the hood. So if you set up a Cloud Functions trigger in Node.js, you can access Admin SDK from the Function itself. For instance, taking a Cloud Storage trigger as an example:
const admin = require('firebase-admin');
admin.initializeApp();
exports.fn = functions.storage.object().onFinalize((object) => {
// Call Admin SDK APIs
});
Similar integrations should be possible with Python as well: https://medium.com/#hiranya911/firebase-using-the-python-admin-sdk-on-google-cloud-functions-590f50226286

Google Cloud functions HTTPS Post Call access Firebase database as non admin to apply rules

My question is very similar to the one found here however that question never seem to get fully answered.
I have a set of HTTPS Post calls within cloud functions that write to my firebase realtime database.
For example:
app.post('/api/dosomething', (req, res) => {
//implementation...
});
The problem is when I write to the DB I am doing so as an admin hence all security rules get ignored.
import * as functions from 'firebase-functions';
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)
I tired the following but receive an error in my functions log
const nonadmin = require('firebase')
nonadmin.initializeApp(functions.config().firebase);
I am having trouble finding documentation on how to obtain a non admin database reference. I read this post here however that is based off of a trigger and using the returned event object. In my cloud function I am using a post request.
There is currently no way to modify the scope of the Firestore SDK to behave as a certain user, in order for security rules to apply. This is something the engineering team is looking into.
The question you linked to is old. Ever since Functions SDK version 1.0, event.data.ref (for Realtime Database) is no longer scoped to the user that made the change. Again, the team is looking into alternatives.
Firebase currently doesn't have a NodeJS client library.
If you really need the security rules to be applied, you can use the REST API. You'd make the call to save/retrieve data with a HTTP Client like axios for example.

Cloud Functions for Firebase HTTP Request

I want to send an HTTP Request from Android to a cloud function, post some values, then input these values into real time database.
index.js
const functions = require('firebase-functions');
exports.testPost = functions.https.onRequest((req, res) => {
console.log(req.body);
});
How can I accomplish this?
I see three steps in here:
Calling a Cloud Function from Android.
This is the same as calling any other HTTP URL from Android. See
Calling a Cloud Function from Android through Firebase
Parsing parameters from the call in your Cloud Function
A HTTP triggered Cloud Function is really just an Express handler. So parsing the post works the same as for other Express handlers. The Firebase documentation for HTTP functions has some examples and links to other documentation.
Posting to the database from a Cloud Functions
All the samples in the functions-samples repo include the Firebase Admin SDK. This SDK allows you to access many Firebase features, such as the database, from within your function. But there's also an example in this repo.

Cloud Functions for Firebase - Getting Network error even though I'm making outbound http request for firebase-admin functionality

I have a functions file where all I'm currently trying to do is access the Firebase auth() functionality to check if a user exists, based on email, and then get their uid.
I have an Angular 2 app where I run an http request to call that function, but any time I try to run it, I get this error:
Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions
Here is my code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
/**
* Function to get a user by email
*/
exports.getUserByEmail = functions.https.onRequest((req, res) => {
console.log('req', req);
return admin.auth().getUserByEmail(req.query.email);
});
Is this type of thing not allows on the Spark plan? I'm still in development of my app and this is the only thing I need working right now and I'd rather not have to start paying right away just to use this tiny feature. Is there anything I can do?
Thanks in advance!
That warning message appears for all functions when executing on the Spark plan. It's just a warning - you can ignore it if you're not doing any outbound networking on your own.
We're looking into getting that message changed or removed so that it's less confusing.
The admin SDK should work fine. However, your function doesn't return a response properly, so it won't appear to do anything. HTTP triggers (please read those docs) must send a response to the client to terminate normally. They don't return promises like the other types of functions.
to be able to make external requests in firebase cloud functions, you have to choose a plan first.
Flame or Blaze plans in console.firebase.google.com

Resources