Nativescript. nativescript-local-notifications always creates two notifications - firebase

I use nativescript-local-notifications and nativescript-plugin-firebase.
I want to create notification each time, when server send me a message. Here is code:
firebase.init({
storageBucket: 'gs://shao-by-partner-firebase.appspot.com',
persist: true, // optional, default false
onPushTokenReceivedCallback: function (token) {
Config.device_token = token;
console.log("Firebase plugin received a push token: " + token);
},
onMessageReceivedCallback: function (message) {
LocalNotifications.schedule([{
id: 1,
title: 'The title',
body: 'Recurs every minute until cancelled',
ticker: 'The ticker',
badge: 1,
smallIcon: 'res://heart.png'
}]).then(
function() {
console.log("Notification scheduled");
},
function(error) {
console.log("scheduling error: " + error);
}
)
}
}).then(
function (result) {
console.log("Firebase is ready");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
}
But always created two notifications instead of one. And first notification is empty. And second notification is that I created. What's wrong?

I could be wrong here, but you are using two plugins to handle remote notifications?
nativescript-plugin-firebase already handles notifications for you, I don't think you need the local notifications plugin.
In the example you posted, you are receiving the original notification (the blank one), pluss the local one that you create in the onMessageReceivedCallback.
https://github.com/EddyVerbruggen/nativescript-plugin-firebase/blob/master/docs/MESSAGING.md#handling-a-notification

The is nothing in your onMessageReceived to determine if the message had any content.
You can try adding a conditional statement to your onMessageReceived function and check if the message has content. eg
if (message.title){
//send local notification
}

I found solution. Each time, when I create LocalNotification, I delete notification with id 0:
LocalNotifications.cancel (0);
But I still don't know,where it comes from.

Related

HMS cancel notification with tag not working ( (HMS push kit)

I am integrating Huawei Push Kit (https://pub.dev/packages/huawei_push) in Flutter application.
I test to schedule a notification to notify every minutes in my Huawei phone, and I able to get the notification as expected. But when I tried to cancel the notification with clearNotification() function (shown below), the notification seem like not cancelled. Wondering do I miss out anything?
scheduleLocalNotification() async {
try {
Map<String, dynamic> localNotification = {
HMSLocalNotificationAttr.TITLE: 'Notification Title',
HMSLocalNotificationAttr.MESSAGE: 'Notification Message',
HMSLocalNotificationAttr.TICKER: "OptionalTicker",
HMSLocalNotificationAttr.TAG: "push-tag",
HMSLocalNotificationAttr.BIG_TEXT: 'This is a bigText',
HMSLocalNotificationAttr.SUB_TEXT: 'This is a subText',
HMSLocalNotificationAttr.LARGE_ICON: 'ic_launcher',
HMSLocalNotificationAttr.SMALL_ICON: 'ic_notification',
HMSLocalNotificationAttr.COLOR: "white",
HMSLocalNotificationAttr.VIBRATE: true,
HMSLocalNotificationAttr.VIBRATE_DURATION: 1000.0,
HMSLocalNotificationAttr.ONGOING: false,
HMSLocalNotificationAttr.DONT_NOTIFY_IN_FOREGROUND: false,
HMSLocalNotificationAttr.AUTO_CANCEL: false,
HMSLocalNotificationAttr.INVOKE_APP: false,
HMSLocalNotificationAttr.ACTIONS: ["Yes", "No"],
HMSLocalNotificationAttr.REPEAT_TYPE: RepeatType.MINUTE,
HMSLocalNotificationAttr.FIRE_DATE:
DateTime.now().add(Duration(minutes: 1)).millisecondsSinceEpoch,
};
Map<String, dynamic> response =
await Push.localNotificationSchedule(localNotification);
print("Scheduled a local notification: " + response.toString());
} catch (e) {
print("Error: " + e.toString());
}
}
clearNotification() async {
Push.cancelNotificationsWithTag('push-tag');
}
Currently, Huawei Push Kit does not support clearNotification() function. You can use the Sending Downlink Messages API. There is an auto_clear parameter, and you can set message display duration, in milliseconds. Messages are automatically deleted after the duration expires.
Please refer to the following code:
{
"validate_only": false,
"message": {
"android": {
"notification":{"body":"Big Boom Body!","click_action":{"type":3},"title":"Big Boom Title","auto_clear": 360000}
},
"token":[
"token1",
"token2"]
}
}
For more information, see docs
Your clearNotification function which calls Push.cancelNotificationWithTag('push-tag') is async.
Possibility is Push.cancelNotificationWithTag might get called before.
Either call it directly and not thru async function or add await.

Add new Subscription to Rocket chat

I want to create a new subscription e.g (stream-all-messages) in Rocket Chat same as stream-room-messages which is already present in docs.
I am using DDP listener to test it, following are the examples which I am trying.
// Subscribe to a message stream from a channel or group
console.log("Attempting to subscribe to the Group/Channel now.\n");
ddpClient.subscribe("stream-room-messages", [RoomId, false], function() {
console.log(ddpClient.collections);
console.log("Subscription Complete.\n");
// Display the stream on console so we can see its working
console.log("\nStarting live-stream of messages.:\n");
ddpClient.on("message", function(msg) {
console.log("Subscription Msg: " + msg);
});
});
above example works because stream-room-messages already present but when I try to execute the following it raises an error i.e.
Subscription Msg: {"msg":"nosub","id":"2","error":{"isClientSafe":true,"error":404,"reason":"Subscription 'stream-only-messages' not found","message":"Subscription 'stream-all-messages' not found [404]","errorType":"Meteor.Error"}}
when I call this
// Subscribe to a message stream from a channel or group
console.log("Attempting to subscribe to the Group/Channel now.\n");
ddpClient.subscribe("stream-all-messages", [RoomId, false], function() {
console.log(ddpClient.collections);
console.log("Subscription Complete.\n");
// Display the stream on console so we can see its working
console.log("\nStarting live-stream of messages.:\n");
ddpClient.on("message", function(msg) {
console.log("Subscription Msg: " + msg);
});
});
Please help me out how can I add a new subscription.

Firebase Phone Auth Error 400

Just getting started with Firebase phone auth. Seems pretty slick however I've hit a wall with a bug.
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "SESSION_EXPIRED"
}
],
"code": 400,
"message": "SESSION_EXPIRED"
}
}
Starting with the Captcha: (standard documentation code!)
var applicationVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
'size': 'invisible',
'callback': function(response) {
},
'expired-callback': function() {
}
});
Its rendered and the captcha works well.
Next is the sign-in bit where you are sent the auth code to your phone. Works great:
$scope.signInWithPhoneNumber = function signInWithPhoneNumber() {
var phoneNumber = "*censored*";
var appVerifier = window.recaptchaVerifier;
firebase.auth().signInWithPhoneNumber(phoneNumber, applicationVerifier)
.then(function (confirmationResult) {
// SMS sent. Prompt user to type the code from the message, then sign the
// user in with confirmationResult.confirm(code).
window.confirmationResult = confirmationResult;
$scope.setConfirmationResult(confirmationResult);
alert('Result: ' + JSON.stringify(confirmationResult));
}).catch(function (error) {
// Error; SMS not sent
alert('Error: ' + error);
// ...
});
};
Finally its the authentication of the code that the user inputs from the text message. Here is when I get the error 400:
$scope.AuthenticateCode = function (code) {
var code = String(document.getElementById("auth_code").value);
var confirmationResult = $scope.getConfirmationResult();
alert(code);
confirmationResult.confirm(code).then(function (result) {
// User signed in successfully.
var user = result.user;
console.log('Signed In! ' + JSON.stringify(user));
// ...
}).catch(function (error) {
// User couldn't sign in (bad verification code?)
// ...
});
}//end of AuthenticateCode
The error is coming from the VerifyPhone method:
https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPhoneNumber?key=censored
Any help or ideas?
Many Thanks,
Kieran
Ok, there are 2 likely reasons:
The code expired. The user took too long to provide the SMS code and finish sign in.
The code was already successfully used. I think this is the likely reason. You need to get a new verificationId in that case. Get a new reCAPTCHA token via the invisible reCAPTCHA you are using.
You are most likely to forget the "Country Code" before the phone no.
That is why firebase throw error 400 which means invalid parameters
If it's an Ionic3 project, change the following lines:
Imports:
import { AngularFireAuth } from 'angularfire2/auth';
import firebase from 'firebase';
Create var:
public recaptchaVerifier: firebase.auth.RecaptchaVerifier;
on "ionViewDidLoad()"
this.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
on "your_method(phoneNumber: number)"
const appVerifier = this.recaptchaVerifier;
const phoneNumberString = "+" + phoneNumber;
this.fireAuth.auth.signInWithPhoneNumber(phoneNumberString, appVerifier)
.then(confirmationResult => {
// SMS sent. Prompt user to type the code from the message, then sign the
// user in with confirmationResult.confirm(code).
let prompt = this.alertCtrl.create({
title: 'Enter the Confirmation code',
inputs: [{ name: 'confirmationCode', placeholder: 'Confirmation Code' }],
buttons: [
{
text: 'Cancel',
handler: data => { console.log('Cancel clicked'); }
},
{
text: 'Send',
handler: data => {
confirmationResult.confirm(data.confirmationCode)
.then(result => {
// Phone number confirmed
}).catch(error => {
// Invalid
console.log(error);
});
}
}
]
});
prompt.present();
})
.catch(error => {
console.error("SMS not sent", error);
});
Reference:
Firebase Phone Number Authentication
I got into a similar situation when a POST request to google API was returning Bad Request 400. When the message was logged, it said:
All requests from this device are blocked due to Unusual Activity. Please try again later
The issue was when the ReCaptcha was sensing a bot out of my development environment and it worked well when I tried later. During the rest of the development, I turned off this feature for easy work.

Parse Server Cloud code keeps sending push notifications

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?

Is there any way for sending push notifications without appcelaretor cloud services?

I already know how to send push notifications in Titanium with Alloy, the way I do is:
// Require the module
var CloudPush = require('ti.cloudpush');
var deviceToken = null;
// Initialize the module
CloudPush.retrieveDeviceToken({
success: deviceTokenSuccess,
error: deviceTokenError
});
// Enable push notifications for this device
// Save the device token for subsequent API calls
function deviceTokenSuccess(e) {
deviceToken = e.deviceToken;
// alert("--->" + deviceToken);
subscribeToChannel();
}
function deviceTokenError(e) {
alert('Failed to register for push notifications! ' + e.error);
}
// Process incoming push notifications
CloudPush.addEventListener('callback', function (evt) {
alert("Notification received: " + evt.payload);
});
// For this example to work, you need to get the device token. See the previous section.
// You also need an ACS user account.
// Require in the Cloud module
var Cloud = require("ti.cloud");
function loginUser(){
// Log in to ACS
Cloud.Users.login({
login: 'example',
password: 'example'
}, function (e) {
if (e.success) {
alert('Login successful');
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
}
function subscribeToChannel(){
// Subscribe the user and device to the 'test' channel
// Specify the push type as either 'android' for Android or 'ios' for iOS
// Check if logged in:
Cloud.PushNotifications.subscribe({
channel: 'test',
//device_token: 'APA91bHRjGoZLCYKwn-XcCtNLETuf-KRKfT4sMgVE4KgXQgInYfZuYTNrZC7FUMugLs0idzzqtLytrvVJjVzYBzQoc7Q81hEerq0O2vww_tV8mACuUfAi0JRvs7LoufnQZpYLZrb_1rlUsIOEMsPxDs9b_pIRJF5rw',
device_token:deviceToken,
type: Ti.Platform.name == 'android' ? 'android' : 'ios'
}, function (e) {
if (e.success) {
alert('Subscribed');
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
}
function unsubscribeToChannel (){
// Unsubscribes the user and device from the 'test' channel
Cloud.PushNotifications.unsubscribe({
channel: 'test',
device_token: deviceToken
}, function (e) {
if (e.success) {
alert('Unsubscribed');
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
}
loginUser();
However this way is only for sending push notification through https://cloud.appcelerator.com/ such a manually because it is needed you write the alert and push the button in that backend site.
So my question: Is there any way for sending push notification in Titanium from an own server in an "automatically" way?
Thanks in advance for any help.
Yes, it is possible.
How to obtain a device token for push notifications is described in the Titanium docs, here.
To send notifications you have to send the token to your server. The server then sends your notification to Apple Push Notification Services (APNS). See Apple docs. That's not "automatic" but it's a simple task for PHP or any other language - you can find a lot of scripts.
You can also schedule local notifications which might come in handy depending on your case.

Resources