Hi i want to send Template notification using azure notification hub. I want to send json object (key value pair) in notification and from app site they will process it and will display. I tried using bellow code but i am not getting notification !
var notificationMessage = new Dictionary<string, string> { { "PushType", "0" }, { "Id","6" }, { "Type", "0"}, { "SubType", "0" }, { "Title", "test" } };
await instance.SendTemplateNotificationAsync(notificationMessage, user.UserID.ToString());
It's hard to tell exactly what is happening without knowing details about code and configuration.
But I would recommend going through the following to troubleshoot:
Azure Notification Hubs - Diagnosis guidelines
Using Azure Notification Hubs Templates
Let me know if you cannot find a solution using links above.
Related
I'm new to programming and I'm developing an app in which the user is suppose to get a notification 30 minutes before an event that's scheduled on the app. The schedule is saved in the firebase database and the device checks every 30 minutes to see if it's time to send an alert. If that condition becomes true, I want the device to send the notification so that the user will be alerted about the event. Every tutorial I saw only showed how to send notification through firebase itself. None of them covered how you can send them from the device.
I came across this code:
final postUrl = Uri.parse('https://fcm.googleapis.com/fcm/send');
final data = {
"registration_ids": tokens, //list of tokens
"collapse_key": "type_a",
"notification": {
"title": 'title',
"body": 'body',
},
"data": {
"data1": 'data 1', //data passed
}
};
final Map<String, String> headers = {
'content-type': 'application/json',
'Authorization': serverKey, //..................FCM server key
};
final response = await http.post(postUrl,
body: json.encode(data),
encoding: Encoding.getByName('utf-8'),
headers: headers);
if (response.statusCode == 200) {
print('test ok push CFM');
return true;
} else {
print(' CFM error');
print(response.statusCode);
return false;
}
}
But isn't this bad practice since your server key is exposed? Are there any better and safe methods to do this using flutter??
I think checking the firebase database every 30 minutes from the device is not a good decision.
You can use/write a firebase cloud function. Using a firebase cloud function you can watch any document/field and try to write notification trigger logic like if a event is before 30 minutes then this cloud function will throw a notification via firebase messaging.
See https://firebase.flutter.dev/docs/functions/overview/ for more information.
I want to send a welcome message (SMS) to phone number of my app's user when they will sign up using their phone number. I couldn't find official documentation for this particular task.
Amazon lets you do this. Assuming you're using Cognito for sign-up, you'll want to use the post-confirmation Cognito lambda trigger.
Set up your SNS account via the AWS Console, to send SMS messages. Send yourself a test message via the console.
Run amplify auth update
When it gets to the question Do you want to configure Lambda Triggers for Cognito?, answer Yes and choose the Post Confirmation trigger
You need to grant SNS (SMS) permissions to the lambda. Update the PostConfirmation-cloudformation-template.json file to add a new statement under Resources.lambdaexecutionpolicy.Properties.PolicyDocument.Statement:
{
"Resources": {
"lambdaexecutionpolicy": {
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": "sns:*",
"Resource": "*"
}
]
...
}
...
}
...
}
...
}
...
}
Use this code for the trigger:
var aws = require('aws-sdk');
var sms = new aws.SNS();
exports.handler = (event, context, callback) => {
console.log(event);
if (event.request.userAttributes.phone_number) {
sendSMS(event.request.userAttributes.phone_number, "Congratulations " + event.userName + ", you have been confirmed: ", function (status) {
// Return to Amazon Cognito
callback(null, event);
});
} else {
// Nothing to do, the user's phone number is unknown
callback(null, event);
}
};
function sendSMS(to, message, completedCallback) {
const params = {
Message: message, /* required */
PhoneNumber: to
};
sns.publish(params, function (err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
} else {
console.log(data);
}
completedCallback("SMS Sent");
})
};
Not sure if sending SMS is a service, Amazon Amplify provides.
But you could use a service like Twilio to send SMS (and much more) to phones.
AWS Amplify can help you setting up SMS, Email and Push notifications to your users by integrating with Amazon Pinpoint. Take a look at the documentation here: https://aws-amplify.github.io/docs/js/push-notifications.
Amazon Pinpoint allows you to create user segmentation, message templates, campaigns (with A/B testing and canary as well), Journeys (for email only so far), and so many more other things. You can integrate it and configure it using AWS Amplify, but some of those features I've mentioned are still not supported by AWS Amplify and you will have to either use the AWS Console to configure or use the AWS SDK to integrate with your app. You can leverage the AWS Amplify Auth module in order to get a valid Cognito token which will allow you to interact with Amazon Pinpoint directly.
I've developed an app that sends push notifications using Parse Server Cloud code. These notifications are received correctly in the devices but hours later they are automatically sent from Parse Server again (and they are received again). This happens 3 or 4 times for each push notifications.
If push notifications are sent from Parse Dashboard they are only sent once, so it seems it's a problem of my cloud code.
This is my code:
Parse.Cloud.define("sendPushNotification", function(request, response) {
var userId = request.params.userId;
var message = request.params.message;
var queryUser = new Parse.Query(Parse.User);
queryUser.equalTo('objectId', userId);
var query = new Parse.Query(Parse.Installation);
query.matchesQuery('user', queryUser);
Parse.Push.send({
where: query,
data: {
alert: message,
badge: 0,
sound: 'default'
}
}, {
success: function() {
console.log('##### PUSH OK');
response.success();
},
error: function(error) {
console.log('##### PUSH ERROR');
response.error('ERROR');
},
useMasterKey: true
});
});
I had a similar issue sending emails from another cloud code function (not included in the question) and my problem was because I forgot to add response.success(); and response.error('ERROR'); methods.
So this time I was sure to include these 2 calls in the responses of "sendPushNotification" method.
After sending a push notification the logs show this:
2017-07-09T15:38:02.427Z - Ran cloud function sendPushNotification for user undefined with:
Input: {"message":"This is my message","userId":"myUserIdInParse"}
Result: undefined
I think that this "Result: undefined" could be related with the problem because success and error functions are not called.
What could be the problem with this code? Why the code doesn't receive a success() when the notifications are received correctly in the devices?
Stopping a watch channel is not working, though it's not responding with an error, even after allowing for propagation overnight. I'm still receiving 5 notifications for one calendarlist change. Sometimes 6. Sometimes 3. It's sporadic. We're also receiving a second round of notifications for the same action after 8 seconds. Sometimes 6 seconds. Sometimes a third set with a random count. Also sporadic. Received a total of 10 unique messages for a single calendar created via web browser.
You can perform infinite amount of watch requests on specific calendar resource, Google will always return the same calendar resource Id for the same calendar, but the uuid you generate in the request will be different, and because of that, you will receive multiple notifications for each watch request that you've made. One way to stop all notifications from specific calendar resource, is to listen for notifications, pull out "x-goog-channel-id" and "x-goog-resource-id" from notification headers, and use them in Channels.stop request.
{
"id": string,
"resourceId": string
}
Every time you perform a watch request, you should persist the data from the response, and check if the uuid or resource id already exist, if yes don't perform watch request for that resource id again (if you don't want to receive multiple notifications).
e.g.
app.post("/calendar/listen", async function (req, res) {
var pushNotification = req.headers;
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.end("Post recieved");
var userData = await dynamoDB.getSignInData(pushNotification["x-goog-channel-token"]).catch(function (err) {
console.log("Promise rejected: " + err);
});
if (!userData) {
console.log("User data not found in the database");
} else {
if (!userData.calendar) {
console.log("Calendar token not found in the user data object, can't perform Calendar API calls");
} else {
oauth2client.credentials = userData.calendar;
await calendarManager.stopWatching(oauth2client, pushNotification["x-goog-channel-id"], pushNotification["x-goog-resource-id"])
}
}
};
calendarManager.js
module.exports.stopWatching = function (oauth2client, channelId, resourceId) {
return new Promise(function (resolve, reject) {
calendar.channels.stop({
auth: oauth2client,
resource: {
id: channelId,
resourceId: resourceId
}
}, async function (err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return reject(err);
} else {
console.log("Stopped watching channel " + channelId);
await dynamoDB.deleteWatchData(channelId)
resolve(response);
}
})
})
}
Not a google expert but I recently implement it in my application,
I am trying to answer some of your questions for future readers:
It's sporadic
Tha's because you have create more than 1 channels for watching events.
We're also receiving a second round of notifications for the same action after 8 seconds
Google doesn't say anything about the maximum delay for sending a push notification.
Suggestions:
CREATE:
When you create a new channel, always save the channel_id and channel_resource in your database.
DELETE:
When you want to delete a channel just use stop API endpoint with the channel data saved in your database
RENEW:
As you have noticed the channels do expire, so you need to update them once in a while. To do that create a crone in your server that is going to STOP all previous channels and it will create new one.
Comment: Whenever something is going wrong please read the error message sent from the Google API calendar. Most of the time, it tells you what is wrong.
Use Channels.stop which is mentioned in the docs. Supply the following data in your request body:
{
"id": string,
"resourceId": string
}
id is the channel ID when you created your watch request. Same goes with resource ID.
Read this SO thread and this github forum for additional reference.
My application uses ACS Push Notification. I have implemented app badge in my application. But the problem is the appBadge doesn't incrementing automatically while receiving a push notification. I have used the following code in my app
var deviceToken;
Titanium.Network.registerForPushNotifications({
types: [
Titanium.Network.NOTIFICATION_TYPE_BADGE,
Titanium.Network.NOTIFICATION_TYPE_ALERT,
Titanium.Network.NOTIFICATION_TYPE_SOUND
],
success:function(e)
{
deviceToken = e.deviceToken;
SubscribeToPush(channelName, deviceToken, type);
},
error:function(e)
{
alert("Error: "+ ((e.error && e.message) || JSON.stringify(e.error)));
},
callback:function(e)
{
var badgeCount = Ti.UI.iPhone.getAppBadge();
badgeCount = badgeCount + 1;
Ti.UI.iPhone.setAppBadge(badgeCount);
}
});
I read here that "callback function" invoked upon receiving a new push notification. So I set the following code as callback to increment the badge.
callback:function(e)
{
var badgeCount = Ti.UI.iPhone.getAppBadge(); //Will return the app badges
badgeCount = badgeCount + 1; //Incrementing the appbadge
Ti.UI.iPhone.setAppBadge(badgeCount); //Setting new appbadge
}
It works while the app is open and when it receives a notification, callback get fired and when the app go to background, the badge get appeared. But I want to increment the badge number when the app is in background or exited. Can anyone help me to resolve this issue?
After lots of research I have created a sample application to increment the appBadge while receiving a server push notification. You can download the code from Increment the ios appBadge Titanium. Please follow the steps after downloading the resources folder.
Create a new mobile application project in Titanium.
Replace the resources folder with the one you downloaded.
Login to www.appcelerator.com, go to your app then go to Manage ACS
Create a new user as admin, set user as admin
Create a new Access Control List(ACS) using the admin user and give the ACL Name as 'SampleApp'
Upload the p12 certificate for push notification
Now Install the application to your iPhone and run the app...
Each user of the app should have a custom object which stores the number of notifications. I'm updating them while sending a push and clears it while I resume/open the application. I tested it with my iPhone devices and it works perfect. However it takes some delays since I have to call ACS multiple times.
UPDATE : Latest Titanium SDKs Support this feature by default.
What you need to do is to change the payload as follows:
var payload = {"alert":"Hi, This is a test notification", badge: "+1"};
/*+1 will increment the current appbadge by 1, number of appbadge will be saved in the ACS*/
Cloud.PushNotifications.notify({
channel: 'friend_request',
payload: payload
}, function (e) {
if (e.success) {
alert('Success');
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
And this will increase the appbadge by one. And you need to reset the appbadge when you resume/open of your application as follows
Cloud.PushNotifications.resetBadge({
device_token : myDeviceToken
}, function(e){
if(e.success){
Ti.UI.iPhone.setAppBadge(0);
} else {
//Error callback
}
})