How can I send a Notification via Firebase Cloud Messaging from a cloud function? - node.js

The documentation at
https://firebase.google.com/docs/reference/admin/node/firebase-admin.messaging.md#getmessaging
does not explain where the "firebase-admin/messaging" module is. What is the require path to get this module?
for instance
const { getMessaging } = require("firebase-admin/messaging");
does not work.
I also looked into the cloud functions sdk at https://firebase.google.com/docs/reference/functions#functions.pubsub where I see the Message class but no way to send a message.

Finally found it:
const messaging = admin.messaging();
which means that the documentation at https://firebase.google.com/docs/cloud-messaging/send-message?authuser=0 is outdated.

Related

Firebase Cloud Messaging - getMessaging is not a function

Trying to send a message from a node.js app in firebase to an android device using code snippets from the firebase website.
https://firebase.google.com/docs/cloud-messaging/android/send-multiple
Keep getting getMessaging is not a function.
My call is await admin.messaging().getMessaging().send(...)
Can't find what is wrong.
The getMessaging() function that you are referring to is a top level function that can be imported from firebase-admin/messaging SDK as shown below:
import { getMessaging } from "firebase-admin/messaging";
This is equivalent of admin.messaging() and both return an instance of Messaging class.
If you are following Firebase documentation to send messages, the code should be:
import { getMessaging } from "firebase-admin/messaging"; // not just "firebase-admin"
const messaging = getMessaging();
await messaging.send(...)
The Admin SDK is not fully modular yet like the the client SDK so rest of the syntax remains same. Also checkout What is the difference between admin.firestore, admin.firestore() and getFirestore()
You're using firebase-admin sdk which does have different syntax. For your use-case, you should instead use:
await admin.messaging().send(...);
For more information, checkout this documentation.

when i use firebase.database().goOnline(); I get an error

this is my code
admin.initializeApp({...});
var db = admin.database();
let ref = db.ref(...);
await ref.once("value",function () {...},);
firebase.database().goOffline();
firebase.database().goOnline();
ref.on("value",function () {...},);
);
when i use firebase.database().goOnline(); I get an error
Firebase: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app/no-app).
at app
You're mixing two ways of addressing Firebase.
You can access Firebase through:
Its client-side JavaScript SDK, in which case the entry point is usually called firebase.
Its server-side Node.js SDK, in which case the entry point is usually called admin.
Now you initialize admin, but then try to access firebase.database(). And since you did call admin.initializeApp that's where the error comes from.
My guess is that you're looking for admin.database().goOnline() or db.goOnline().
Also note that there is no reason to toggle goOffline()/goOnline() in the way you do now, and you're typically better off letting Firebase manage that on its own.

Implementing isRequestFromAssistant in Node.js on actions-on-google project fulfillment

I am having trouble implementing the isRequestFromAssistant method to verify requests to my fulfillment webhook. Using Node.js, I instantiate the following variables at the start of my index.js file:
const App = require('actions-on-google').ApiAiApp;
const app = new App({ request, response });
I then use "app" with the .ask and .tell and other methods throughout my functions.
The code I see in the docs for implementing isRequestFromAssistant is:
const app = new ActionsSdkApp({request, response});
app.isRequestFromAssistant('my-project-id')
.then(() => {
app.ask('Hey there, thanks for stopping by!');
})
.catch(err => {
response.status(400).send();
});
If I leave out the first line and use my existing app variable, created with the .ApiAi method instead of the .ActionsSdkApp method, it doesn't work. If I create a new variable App1 and app1 using the .ActionsSdkApp method and change the above code to be app1.isRequestFromAssistant, it also doesn't work. I have tried other variations with no luck.
When I say it doesn't work, I mean I receive a 500 Internal Server Error when I call it. I am hosting it with NGROK currently. I am still a beginner with Node.js, although I have managed to get the other 700 lines of code working just fine, learning mostly from Google searches and reading these forums.
You have a few things going on here which, individually or separately, may be causing the problem.
First - make sure you have the most recent version of the actions-on-google library. The isRequestFromAssistant() function was added in version 1.6.0, I believe.
Second - Make sure you're creating the right kind of App instance. If you're using Dialogflow (formerly API.AI), you should be creating it with something like
const App = require('actions-on-google').DialogflowApp;
const app = new App( {request, response} );
or
const { DialogflowApp } = require('actions-on-google');
const app = new DialogflowApp( {request, response} );
(They both do the same thing, but you'll see both forms in documentation.) You should switch to DialogflowApp from ApiAiApp (which your example uses) to reflect the new name, but the old form has been retained.
If you're using the Actions SDK directly (not using Dialogflow / API.AI), then you should be using the ActionsSdkApp object, something like
const { ActionsSdkApp } = require('actions-on-google');
const app = new ActionsSdkApp({request: request, response: response});
(Again, you'll see variants on this, but they're all fundamentally the same.)
Third - Make sure you're using the right function that matches the object you're using. The isRequestFromAssistant() function is only if you are using the Actions SDK.
If you are using Dialogflow, the corresponding function is isRequestFromDialogflow(). The parameters are different, however, since it requires you to set confirmation information as part of your Dialogflow configuration.
Finally - If you're getting a 500 error, then check your logs (or the output from stderr) for the node.js server that is running. Typically there will be an error message there that points you in the right direction. If not - posting that error message as part of your StackOverflow question is always helpful.
Set the secure (randomly generated) auth header & key values in the dialogflow Fulfillment page, then in nodejs:
if (app.isRequestFromDialogflow("replace_with_key", "replace_with_value")) {
console.log("Request came from dialogflow!");
// rest of bot
} else {
console.log("Request did not come from dialogflow!");
response.status(400).send();
}
Also see: https://developers.google.com/actions/reference/nodejs/DialogflowApp#isRequestFromDialogflow

'context.getTwilioClient(...).document is not a function?

I'm working with Twilio Functions and I'm trying to use Sync Documents but I keep getting this error: context.getTwilioClient(...).document is not a function
exports.handler = function(context, event, callback) {
context.getTwilioClient().document('data').then(function(doc) {..});
};
Twilio developer evangelist here.
As Andy said, the client you retrieve from context.getTwilioClient() is a generic Twilio REST API client that can access all the resources.
To get your document you need to traverse the objects in the client and get a handle on your service. You need the Sync Service SID, ideally in your environment variables, and the code would look like this:
const client = context.getTwilioClient();
const service = client.sync.services(process.env.SYNC_SERVICE_SID);
service.document('data').fetch().then(function(doc) {
// do something with the document.
});
Let me know if that helps at all.

The Syntax to call a Google Cloud Function from another Google Cloud Function

I want to make a Google Cloud Function with HTTP trigger that call another function (example: changeString). I know that I can include the function changeString in index.js. However, I want to reuse changeString so others Google Cloud Functions can call it.
exports.helloWorld = function helloWorld(req, res) {
var result = changeString(req.body.string);
res.send(result);
};
I know that there is a similar question, but it did not solve my problem.
I was wondering about this myself and I think the answer is that you don’t call the function. Instead, you should send a payload to the PubSub service from your HTTP Cloud Function. A secondary Cloud Function subscribes to the PubSub topic and consumes the payload (which is Base64 encoded).
As #user3158158 brings out, you would publish a message to a Pub/Sub service. This is highlighted here: https://cloud.google.com/functions/docs/calling/pubsub#publishing_a_message_from_within_a_function
I shows the sample syntax at the above link, I needed to do the same thing today.

Resources