IBM Worklight push notification not showing after authentication - push-notification

Hi I have a very strange Push Notification issue. I tried with the provided PushNotification project and everything worked fine for me. But now in my app when I tried to implement it in a similar manner I got this issue.
So what I have done is in my main.js file I have added the following code for the user to be able to subscribe.
if (WL.Client.Push){
WL.Client.Push.onReadyToSubscribe = function(){
alert("onReadyToSubscribe");
alert("You said yes");
WL.Client.Push.registerEventSourceCallback(
"myPush1",
"PushAdapter",
"PushEventSource1",
pushNotificationReceived);
if(!WL.Client.Push.isSubscribed("myPush1"))
{
if(confirm('Do you allow CSOL to send notification to you?')) {
WL.Client.Push.subscribe("myPush1", {
onSuccess: doSubscribeSuccess,
onFailure: doSubscribeFailure
});
}
}
else
{
alert(WL.Client.Push.isSubscribed("myPush1"));
}
};
}
PushAdapter-impl.js
/*
* Licensed Materials - Property of IBM
* 5725-G92 (C) Copyright IBM Corp. 2006, 2013. All Rights Reserved.
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
WL.Server.createEventSource({
name: 'PushEventSource1',
onDeviceSubscribe: 'deviceSubscribeFunc',
onDeviceUnsubscribe: 'deviceUnsubscribeFunc',
securityTest:'PushApplication-strong-mobile-securityTest'
});
function deviceSubscribeFunc(userSubscription, deviceSubscription){
WL.Logger.debug(">> deviceSubscribeFunc");
WL.Logger.debug(userSubscription);
WL.Logger.debug(deviceSubscription);
}
function deviceUnsubscribeFunc(userSubscription, deviceSubscription){
WL.Logger.debug(">> deviceUnsubscribeFunc");
WL.Logger.debug(userSubscription);
WL.Logger.debug(deviceSubscription);
}
function javaCheck(requestID, oldStatus, newStatus){
return {
result : com.ibm.mycsol.pushdemo.push(requestID, oldStatus, newStatus)
};
}
function submitNotification(userId, notificationText){
//userId = WL.Server.getActiveUser()
var userSubscription = WL.Server.getUserNotificationSubscription('PushAdapter.PushEventSource1', userId);
if (userSubscription==null){
return { result: "No subscription found for user :: " + userId };
}
var badgeDigit = 1;
var notification = WL.Server.createDefaultNotification(notificationText, 1, {userId:userId});
WL.Logger.debug("submitNotification >> userId :: " + userId + ", text :: " + notificationText);
//WL.Server.notifyAllDevices(userSubscription, notification);
WL.Server.notifyAllDevices(userSubscription, notification);
return {
result: "Notification sent to user :: " + userId
};
}
Everything works fine when I have the app in the foreground. Or when I have pressed the home button on my phone I receive the notification and clicking on the notification reopens the app and shows the specific notification. But when I press the backbutton or I logout I receive the notification, clicking on the notification takes me back to the app and asks me for login. But once I login I am not able to see the notification.
I am using a custom login module which checks the username password against a hardcoded string value.
Here is the log
02-27 11:50:21.981: V/WebViewInputDispatcher(30541): blockWebkitDraw
02-27 11:50:21.981: V/WebViewInputDispatcher(30541): blockWebkitDraw lockedfalse
02-27 11:50:22.286: D/webview(30541): blockWebkitViewMessage= false
02-27 11:50:22.336: D/myCSOLApp(30541): Request [login]
02-27 11:50:22.351: D/ProgressBar(30541): setProgress = 0
02-27 11:50:22.351: D/ProgressBar(30541): setProgress = 0, fromUser = false
02-27 11:50:22.351: D/ProgressBar(30541): mProgress = 0mIndeterminate = false, mMin = 0, mMax = 10000
02-27 11:50:22.381: D/dalvikvm(30541): GC_FOR_ALLOC freed 277K, 20% free 10773K/13392K, paused 11ms, total 11ms
02-27 11:50:22.411: D/dalvikvm(30541): GC_FOR_ALLOC freed 376K, 19% free 10877K/13392K, paused 10ms, total 10ms
02-27 11:50:22.426: D/WebView(30541): onSizeChanged - w:320 h:547
02-27 11:50:22.481: D/ProgressBar(30541): updateDrawableBounds: left = 0
02-27 11:50:22.481: D/ProgressBar(30541): updateDrawableBounds: top = 0
02-27 11:50:22.481: D/ProgressBar(30541): updateDrawableBounds: right = 48
02-27 11:50:22.481: D/ProgressBar(30541): updateDrawableBounds: bottom = 48
02-27 11:50:22.556: D/myCSOLApp(30541): Request [http://9.127.62.227:10080/MYCSOL/apps/services/api/myCSOLApp/android/query]
02-27 11:50:22.621: D/myCSOLApp(30541): Request [http://9.127.62.227:10080/MYCSOL/apps/services/api/myCSOLApp/android/query]
02-27 11:50:22.756: D/ProgressBar(30541): setProgress = 0
02-27 11:50:22.756: D/ProgressBar(30541): setProgress = 0, fromUser = false
02-27 11:50:22.756: D/ProgressBar(30541): mProgress = 0mIndeterminate = false, mMin = 0, mMax = 10000
02-27 11:50:22.761: D/myCSOLApp(30541): Request [http://9.127.62.227:10080/MYCSOL/apps/services/api/myCSOLApp/android/query]
02-27 11:50:22.806: D/ProgressBar(30541): updateDrawableBounds: left = 0
02-27 11:50:22.806: D/ProgressBar(30541): updateDrawableBounds: top = 0
02-27 11:50:22.806: D/ProgressBar(30541): updateDrawableBounds: right = 48
02-27 11:50:22.806: D/ProgressBar(30541): updateDrawableBounds: bottom = 48
02-27 11:50:22.846: E/ViewRootImpl(30541): sendUserActionEvent() mView == null
02-27 11:50:30.956: D/myCSOLApp(30541): Clearing notification subscriptions.
02-27 11:50:30.956: D/myCSOLApp(30541): Updating notification subscriptions.
02-27 11:50:30.961: D/WLDroidGap(30541): unregisterReceivers:Receiver not registered: null
02-27 11:50:30.961: D/WLDroidGap(30541): unregisterReceivers:Receiver not registered: null
02-27 11:50:30.966: D/WLDroidGap(30541): Activity started from message notification
02-27 11:50:30.966: D/WLDroidGap(30541): Queuing message for dispatch to javascript
02-27 11:50:30.966: D/WLDroidGap(30541): dispatchPending called. Number of pending messages: 1
02-27 11:50:30.966: W/ResourceType(30541): No package identifier when getting name for resource number 0x00000064
02-27 11:50:30.966: D/WLDroidGap(30541): dispatchPending webView=com.worklight.androidgap.WLWebView{4285e1d8 VFEDH.CL .F....I. 0,0-320,547 #64} messageCallback=null
02-27 11:50:30.966: D/WLDroidGap(30541): dispatchPending called. Number of pending messages: 1
02-27 11:50:30.966: W/ResourceType(30541): No package identifier when getting name for resource number 0x00000064
02-27 11:50:30.966: D/WLDroidGap(30541): dispatchPending webView=com.worklight.androidgap.WLWebView{4285e1d8 VFEDH.CL .F....I. 0,0-320,547 #64} messageCallback=null
02-27 11:50:30.966: V/GCMRegistrar(30541): Registering receiver
02-27 11:50:30.966: D/GCMRegistrar(30541): resetting backoff for com.myCSOLApp
02-27 11:50:30.971: V/GCMRegistrar(30541): Registering app com.myCSOLApp of senders 774173770625
02-27 11:50:30.986: D/myCSOLApp(30541): response [http://9.127.62.227:10080/MYCSOL/apps/services/api/myCSOLApp/android/query] success: /*-secure-
02-27 11:50:30.986: D/myCSOLApp(30541): {"totalTime":8024,"isSuccessful":true,"requests":[{"isFav":"N","comments":[{"SEQNO":"1122","USERNAME":"EDGAR2 CAMARENA2テスト","COMMENTTYPE":"BP","REQUESTCOMMENT_ID":"20879","REQUESTID":"GASUK1402261122","COMMENTTEXT":"sdfdsf","UPDTIMESTAMP":"2014-02-26 13:52:59.684675","ANSWER":"","UPDUSERID":"ecamaren#mx1.ibm.com"}],"REQTYPE":"Create new maintenance proposal","REQUESTID":"GASUK1402261122","TYPE":"TSSP","WWW_STATUS":"Submitted","UPDTIMESTAMP":""},{"isFav":"N","comments":[{"SEQNO":"1121","USERNAME":"EDGAR2 CAMARENA2テスト","COMMENTTYPE":"BP","REQUESTCOMMENT_ID":"20878","REQUESTID":"GASUK1402261121","COMMENTTEXT":"sdfsdf","UPDTIMESTAMP":"2014-02-26 13:08:41.661944","ANSWER":"","UPDUSERID":"ecamaren#mx1.ibm.com"}],"REQTYPE":"Create new maintenance proposal","REQUESTID":"GASUK1402261121","TYPE":"TSSP","WWW_STATUS":"Submitted","UPDTIMESTAMP":""}],"stat":"ok","responseHeaders":{"Server":"WebSphere Application Server\/8.5","X-Powered-By":"Servlet\/3.0","Transfer-Encoding":"chunked","Content-Language":"en-US","Content-Type":"application\/json","Date":"Thu, 27 Feb 2014 03:50:32 GMT"},"WL-Authentication-Success":{"wl_deviceNoProvisioningRealm":{"userId":"0afa2eb3-708a-3b1e-a2cf-79f4afe26820","attributes":{"mobileClientData":"com.worklight.core.auth.ext.MobileClientData#2db9f248"},"isUserAuthenticated":1,"displayName":"0afa2eb3-708a-3b1e-a2cf-79f4afe26820"},"wl_antiXSRFRealm":{"userId":"hq7l1qekklblb3lfa2no754oc6","attributes":{},"isUserAuthenticated":1,"displayName":"hq7l1qekklblb3lfa2no754oc6"},"wl_remoteDisableRealm":{"userId":"null","attributes":{},"isUserAuthenticated":1,"displayName":"null"},"CustomAuthenticatorRealm":{"userId":"ecamaren#mx1.ibm.com","attributes":{"AuthenticationDate":"Thu Feb 27 11:50:24 SGT 2014","userIdentity":null},"isUserAuthenticated":1,"displayName":null}},"statusReason":"OK","notificationSubscriptionState":{"token":"APA91bGYP18rdbg_25Ginyts3qGmCPDMqLV4AEQARVEFSARyKyGexuKFIhuloZbg0tWzzq_35fURNdKTNNJYsWFnBv3Yk7VndDVIXKENS9kJb7byAuolhZpISM_lH9FEZuyXb8dv3zokJLuynDQm9URZ5EY9x1UeuA","eventSources":[{"alias":"myPush1","eventSource":"PushEventSource1","adapter":"PushAdapter"}]},"responseID":"11","responseTime":8024,"statusCode":200}*/
02-27 11:50:31.031: E/ViewRootImpl(30541): sendUserActionEvent() mView == null
02-27 11:50:31.066: E/myCSOLApp(30541): [http://9.127.62.227:10080/MYCSOL/apps/services/api/myCSOLApp/android/query] exception. TypeError: Cannot read property 'user' of null
02-27 11:50:31.081: D/CordovaLog(30541): Uncaught TypeError: Cannot read property 'user' of null
02-27 11:50:31.081: E/Web Console(30541): Uncaught TypeError: Cannot read property 'user' of null:1714
02-27 11:50:31.216: D/myCSOLApp(30541): response [http://9.127.62.227:10080/MYCSOL/apps/services/api/myCSOLApp/android/query] success: /*-secure-
02-27 11:50:31.216: D/myCSOLApp(30541): {"totalTime":8508,"isSuccessful":true,"requests":[{"isFav":"N","comments":[{"SEQNO":"1124","USERNAME":"EDGAR2 CAMARENA2テスト","COMMENTTYPE":"BP","REQUESTCOMMENT_ID":"20881","REQUESTID":"GASUK1402261124","COMMENTTEXT":"sdfsdf","UPDTIMESTAMP":"2014-02-26 14:47:40.002743","ANSWER":"","UPDUSERID":"ecamaren#mx1.ibm.com"}],"REQTYPE":"Accept maintenance contract","REQUESTID":"GASUK1402261124","TYPE":"TSSC","WWW_STATUS":"Submitted","UPDTIMESTAMP":""},{"isFav":"N","comments":[{"SEQNO":"1123","USERNAME":"EDGAR2 CAMARENA2テスト","COMMENTTYPE":"BP","REQUESTCOMMENT_ID":"20880","REQUESTID":"GASUK1402261123","COMMENTTEXT":"dfgdf","UPDTIMESTAMP":"2014-02-26 14:34:24.679642","ANSWER":"","UPDUSERID":"ecamaren#mx1.ibm.com"}],"REQTYPE":"Accept maintenance contract","REQUESTID":"GASUK1402261123","TYPE":"TSSC","WWW_STATUS":"Submitted","UPDTIMESTAMP":""}],"stat":"ok","responseHeaders":{"Server":"WebSphere Application Server\/8.5","X-Powered-By":"Servlet\/3.0","Transfer-Encoding":"chunked","Content-Language":"en-US","Content-Type":"application\/json","Date":"Thu, 27 Feb 2014 03:50:33 GMT"},"statusReason":"OK","responseID":"12","responseTime":8508,"statusCode":200}*/
02-27 11:50:31.271: E/myCSOLApp(30541): [http://9.127.62.227:10080/MYCSOL/apps/services/api/myCSOLApp/android/query] exception. TypeError: Cannot read property 'user' of null
02-27 11:50:31.286: D/CordovaLog(30541): Uncaught TypeError: Cannot read property 'user' of null
02-27 11:50:31.286: E/Web Console(30541): Uncaught TypeError: Cannot read property 'user' of null:1714
02-27 11:50:31.436: V/GCMBroadcastReceiver(30541): onReceive: com.google.android.c2dm.intent.REGISTRATION
02-27 11:50:31.436: V/GCMBroadcastReceiver(30541): GCM IntentService class: com.myCSOLApp.GCMIntentService
02-27 11:50:31.436: V/GCMBaseIntentService(30541): Acquiring wakelock
02-27 11:50:31.441: V/GCMBaseIntentService(30541): Intent service name: GCMIntentService-774173770625-2
02-27 11:50:31.446: D/GCMBaseIntentService(30541): handleRegistration: registrationId = APA91bGYP18rdbg_25Ginyts3qGmCPDMqLV4AEQARVEFSARyKyGexuKFIhuloZbg0tWzzq_35fURNdKTNNJYsWFnBv3Yk7VndDVIXKENS9kJb7byAuolhZpISM_lH9FEZuyXb8dv3zokJLuynDQm9URZ5EY9x1UeuA, error = null, unregistered = null
02-27 11:50:31.446: D/GCMRegistrar(30541): resetting backoff for com.myCSOLApp
02-27 11:50:31.446: V/GCMRegistrar(30541): Saving regId on app version 1
02-27 11:50:31.446: D/WLDroidGap(30541): Registered at the GCM server with registration id APA91bGYP18rdbg_25Ginyts3qGmCPDMqLV4AEQARVEFSARyKyGexuKFIhuloZbg0tWzzq_35fURNdKTNNJYsWFnBv3Yk7VndDVIXKENS9kJb7byAuolhZpISM_lH9FEZuyXb8dv3zokJLuynDQm9URZ5EY9x1UeuA
02-27 11:50:31.451: V/GCMBaseIntentService(30541): Releasing wakelock
02-27 11:50:31.451: D/CallbackProxy(30541): sendMessageToUiThreadSync Package=com.myCSOLApp message=112
02-27 11:50:31.491: D/TextLayoutCache(30541): Enable myanmar Zawgyi converter
02-27 11:50:31.491: D/TextLayoutCache(30541): Enable myanmar Zawgyi converter
02-27 11:50:31.491: D/TextLayoutCache(30541): Enable myanmar Zawgyi converter
02-27 11:50:31.516: D/TextLayoutCache(30541): Enable myanmar Zawgyi converter
02-27 11:50:31.516: D/TextLayoutCache(30541): Enable myanmar Zawgyi converter
02-27 11:50:31.521: D/TextLayoutCache(30541): Enable myanmar Zawgyi converter
I am trying it on a Samsung phone. The LogCat shows that all pending notifications have been dispatched. When I tried to call WL.Client.Push.__hasPendings() it returns false. But when another new notification comes now when the app is in foreground the old notification shows up. So what could be the possible problem ??

I worked it out by calling the android functions directly in my code.
if (WL.Client.Push){
WL.Client.Push.onReadyToSubscribe = function(){
alert("onReadyToSubscribe");
alert("You said yes");
WL.Client.Push.registerEventSourceCallback(
"myPush1",
"PushAdapter",
"PushEventSource1",
pushNotificationReceived);
if(!WL.Client.Push.isSubscribed("myPush1"))
{
if(confirm('Do you allow CSOL to send notification to you?')) {
WL.Client.Push.subscribe("myPush1", {
onSuccess: doSubscribeSuccess,
onFailure: doSubscribeFailure
});
}
}
else
{
if(WL.Client.Push.__hasPendings()){
WL.Client.Push.__dispatchPendings();
}
cordova.exec(null, null, 'Push', 'dispatch', [ 'WL.Client.Push.__onmessage' ]);
//cordova.exec("Push.dispatch", 'WL.Client.Push.__onmessage');
}
};
}

Related

Xamarin.Forms push-notifications are transmitted very unreliably (late or not at all)

I am writing an Xamarin.forms based app which is currently running on android platform. It is the first time I need to use push-notifications. I followed a guide from microsoft (https://learn.microsoft.com/de-de/xamarin/android/data-cloud/google-messaging/remote-notifications-with-fcm?tabs=vswin)") to implement the notifications.
The target android version is 8.1 API 27. The app runs on a Samsung tab active 2, which has android 8.1.
I configured the app as seen in the tutorial. I push the messages through a defined channel and this channel is subscribed in the app. The messages are pushed by a server which triggers the rest call for the FCM api. The first day I did some tests the transmission worked very good and I would say it was (nearly) reliable.
The next day I implemented some other features and wanted to test the push notifications again. Then: I was very confused, the most messages were not delivered or VERY VERY late. I am not sure if all messages were transmitted, there went may be some lost.
For me the FCM service is a big blackbox where I can delegate some work and then I need to hope that the messages will be transmitted. I am very confused now.
I paste here some code, but it is nearly what you can find in the tutorial:
My Questions:
What can I do? Is there something to get some more information from the FCM what my messages are currently doing? Or are there some problems with the code?
This is run in the mainActivity:
if (this.IsPlayServicesAvailable())
{
// Creates a notification channel
this.CreateNotificationChannel();
//Console.WriteLine("InstanceID token: " + FirebaseInstanceId.Instance.Token);
// Subscribe to notification token
FirebaseMessaging.Instance.SubscribeToTopic("channel");
Log.Debug(TAG, "Subscribed to remote notifications");
}
This checks if the channel can be created and creates it: (is called in the mainActivity)
private void CreateNotificationChannel()
{
// The app is not running on Android 8.0 or higher
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
// Create a notification channel for publishing notifications
var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Default)
{
Description = "Firebase Cloud Messages appear in this channel"
};
var notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
This checks if playServices are available: (also called in mainActivity)
public bool IsPlayServicesAvailable()
{
int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.Success)
{
if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode))
{
Log.Debug(TAG, GoogleApiAvailability.Instance.GetErrorString(resultCode));
}
else
{
Log.Debug(TAG, "This device has no compatible Google Play services APK - Download an APK from the Google Play Store or to enable it in the device's system settings!");
Finish();
}
return false;
}
else
{
Log.Debug(TAG, "Google Play Services are available.");
return true;
}
}
The last snipped is the service to handle a notification and inform the user:
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class CustomFirebaseMessagingService : FirebaseMessagingService
{
// Logging Tag
private static readonly string TAG = "CustomFirebaseMessagingService";
/* Handles data messages and notifications messages if the app is in foreground.
*
* Apps only have 10 seconds in which to handle an incoming Firebase Cloud Message.
* Any work that takes longer than this should be scheduled for background execution using a library such as the 'Android Job Scheduler' or the 'Firebase Job Dispatcher'.
*
*/
public override void OnMessageReceived(RemoteMessage message)
{
Log.Debug(TAG, "Message from: " + message.From);
// If the message data payload is not empty, display a notification
if (message.Data.Count > 0)
{
Log.Debug(TAG, "Data Payload: " + message.Data.ToString());
this.SendNotification(message.Data);
}
}
// Converts the incoming FCM message into a local notification
private void SendNotification(IDictionary<string, string> data)
{
Console.WriteLine("Push Message received");
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
if (data.TryGetValue("message", out string message))
{
foreach (var key in data.Keys)
{
intent.PutExtra(key, data[key]);
}
var pendingIntent = PendingIntent.GetActivity(this, MainActivity.NOTIFICATION_ID, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.NotificationIcon)
.SetContentTitle("TITEL")
.SetContentText(message)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManagerCompat.From(this);
notificationManager.Notify(MainActivity.NOTIFICATION_ID, notificationBuilder.Build());
}
}
}

FCM on iOS An error occured on client IDB480752 while executing a reply for topic xvs/idb/4.8.0.752/stop-app

I added firecloud messaging to my iOS app as described here https://components.xamarin.com/gettingstarted/firebaseioscloudmessaging#subscribe-the-client-app-to-a-topic and it seems to work fine for both foreground and background notificaitons on initial run of the app. I am actually using the nuget Xamarin.Firebase.iOS.CloudMessaging not the component.
When I open the app a second time after having sent at least one push notification I get this error at launch in the debug output.
An error occured on client IDB480752 while executing a reply for topic xvs/idb/4.8.0.752/stop-app
Looking at the ide logs gives a little more detail.
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
2018-02-16 16:47:54.525 RecoveryConnect_Mobile_PCLiOS[1018:3202793] Encounter network error. Code, error: -1200, Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"",
""
), NSUnderlyingError=0x10b0f5190 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"",
""
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://play.googleapis.com/log, NSErrorFailingURLStringKey=https://play.googleapis.com/log, NSErrorClientCertificateStateKey=0}
The app has been terminated.
Failed to Stop app: An error occured on client IDB480752 while executing a reply for topic xvs/idb/4.8.0.752/stop-app
The app has been terminated.
public partial class AppDelegate :
global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate,
IUNUserNotificationCenterDelegate, IMessagingDelegate
{
global::Xamarin.Forms.Forms.Init();
global::Xamarin.FormsMaps.Init();
App.BuildNumber = NSBundle.MainBundle.InfoDictionary[new
NSString("CFBundleVersion")].ToString();
LoadApplication(new App());
RegisterForPushNotifications();
return base.FinishedLaunching(app, options);
}
public override void DidEnterBackground(UIApplication uiApplication)
{
//Messaging.SharedInstance.ShouldEstablishDirectChannel = false;
Messaging.SharedInstance.Disconnect();
}
public override void OnActivated(UIApplication uiApplication)
{
ConnectFCM();
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
base.OnActivated(uiApplication);
}
private void RegisterForPushNotifications()
{
try
{
Firebase.Core.App.Configure();
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
// iOS 10 or later
var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) => {
Console.WriteLine(granted);
});
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.Current.Delegate = this;
// For iOS 10 data message (sent via FCM)
Messaging.SharedInstance.RemoteMessageDelegate = this;
}
else
{
// iOS 9 or before
var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
UIApplication.SharedApplication.RegisterForRemoteNotifications();
Firebase.InstanceID.InstanceId.Notifications.ObserveTokenRefresh((sender, e) =>
{
var newToken = Firebase.InstanceID.InstanceId.SharedInstance.Token;
var FCMTokenRegistration = new Models.Model_FCMToken(newToken);
FCMTokenRegistration.StoreToken();
// if you want to send notification per user, use this token
System.Diagnostics.Debug.WriteLine(newToken);
ConnectFCM();
});
}
catch(System.Exception ex)
{
Helpers.Helper_ErrorHandling.SendErrorToServer(ex);
}
}
private void ConnectFCM()
{
Messaging.SharedInstance.Connect(error => {
if (error != null)
{
// Handle if something went wrong while connecting
}
else
{
// Let the user know that connection was successful
}
});
}
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired 'till the user taps on the notification launching the application.
// Do your magic to handle the notification data
System.Console.WriteLine(userInfo);
}
// To receive notifications in foreground on iOS 10 devices.
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
// Do your magic to handle the notification data
System.Console.WriteLine(notification.Request.Content.UserInfo);
}
// Receive data message on iOS 10 devices.
public void ApplicationReceivedRemoteMessage(RemoteMessage remoteMessage)
{
Console.WriteLine(remoteMessage.AppData);
}
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
{
// Do your magic to handle the notification data
System.Console.WriteLine("");
}
public void DidRefreshRegistrationToken(Messaging messaging, string fcmToken)
{
var token = fcmToken;
//var newToken = Firebase.InstanceID.InstanceId.SharedInstance.Token;
//var FCMTokenRegistration = new Models.Model_FCMToken(newToken);
//FCMTokenRegistration.StoreToken();
//// if you want to send notification per user, use this token
//System.Diagnostics.Debug.WriteLine(newToken);
//ConnectFCM();
}
I did try adding NSAppTransportSecurity for arbitrary loads with no avail.

Firebase APN notification are not in the tray when app is in the background

For some reason notifications sent via Firebase don't get in the tray when the app is in the background. Here's the code that initialises Firebase (we're currently testing on iOS 10 using Xamarin in VS 2017). In AppDelegate.cs:
public void InitFirebase()
{
// Configure Firebase
App.Configure();
// Register your app for remote notifications.
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
// iOS 10 or later
var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) =>
{
Log.Info("BoaTan", "RequestAuthorization: {0}", granted);
});
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.Current.Delegate = this;
// For iOS 10 data message (sent via FCM)
Firebase.CloudMessaging.Messaging.SharedInstance.RemoteMessageDelegate = this;
// Monitor token generation
InstanceId.Notifications.ObserveTokenRefresh((sender, e) =>
{
Log.Info("BoaTan", "New firebase token received {0}", PlatformEntrance.Token);
LoginViewModel viewModel = LoginView.Me.ViewModel as LoginViewModel;
viewModel.UpdateFirebaseToken(PlatformEntrance.Token);
});
Firebase.CloudMessaging.Messaging.SharedInstance.Connect(error =>
{
if (error != null)
{
Log.Error("BoaTan", error.DebugDescription);
}
else
{
Log.Info("BoaTan", "Connection to Firebase messaging succeeded");
}
});
// Monitor token generation
InstanceId.Notifications.ObserveTokenRefresh((sender, e) =>
{
SendTokenToServer();
});
}
else
{
// iOS 9 or before
var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
In the AppDelegate.cs we also have the following code to receive the messages:
public override void WillEnterForeground(UIApplication application)
{
Firebase.CloudMessaging.Messaging.SharedInstance.Connect((NSError error) =>
{
Log.Info("BoaTan", "WillEnterForeground: Connected to Firebase messaging ({0})", error?.Description);
});
base.WillEnterForeground(application);
}
public override void DidEnterBackground(UIApplication application)
{
Firebase.CloudMessaging.Messaging.SharedInstance.Disconnect();
Log.Info("BoaTan", "DidEnterBackground: Disconnected from Firebase messaging");
base.DidEnterBackground(application);
}
// To receive notifications in foregroung on iOS 9 and below.
// To receive notifications in background in any iOS version
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
Log.Info("BoaTan", "DidReceiveRemoteNotification: Disconnected from Firebase messaging");
SendDataMessage(userInfo);
}
// To receive notifications in foreground on iOS 10 devices.
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
Log.Info("BoaTan", "WillPresentNotification: Disconnected from Firebase messaging");
SendDataMessage(notification.Request.Content.UserInfo);
}
public void ApplicationReceivedRemoteMessage(RemoteMessage message)
{
SendDataMessage(message.AppData);
}
/// <summary>
/// Use MvvmCross messaging to send a message to subcribers.
/// </summary>
/// <param name="dictionary"></param>
private void SendDataMessage(NSDictionary dictionary)
{
LogReceivedInfo(dictionary);
NSObject data;
NSString key = new NSString("data");
if (dictionary.TryGetValue(key, out data))
{
Log.Info("BoaTan", "Data: {0}", data);
Settings.Notification = JsonConvert.DeserializeObject<LoginNotificationParameter>((NSString)data);
ServicesHelper.SendMessage(this);
}
}
private void LogReceivedInfo(NSDictionary keyvalues)
{
Log.Info("BoaTan", "-----------------------------------------------------------");
foreach (var keyval in keyvalues)
{
Log.Info("BoaTan", "Key: {0} Value: {1}", keyval.Key, keyval.Value);
}
Log.Info("BoaTan", "-----------------------------------------------------------");
}
}
Message arrive perfectly when the App is in the foreground. All messages are queued until the App gets in the Foreground again.
This is in the info.plist:
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
<string>fetch</string>
</array>
When I go to the Firebase console and compose a message there in several variants the messages also don't arrive in the tray which leads me to the following conclusions:
The App is missing some configuration telling iOS I'm expecting messages.
Something missing is the configuration of APN at the Apple developer console.
Something missing in the Firebase/iOS configuration/initialization.
The permutations are endless. Who has the answer? And then there is still the challenge of iOS 9.
I have no experiences with Firebase on iOS but on Android I had the same problem.
Firebase has two types of messages: Notification message and Data message, see About FCM Messages
On Android the Notification message is only visible when the app is in foreground. Maybe this is also your problem
Don't know exactly why it started working but it works now. After deleting the App from my iPad and reinstalling it the tray started working too. My guess is that a redeploy keeps setting as they are and after a reinstall these were set correctly.

SignalR messages passing through Azure Service Bus are not propagating to SignalR web clients

I want to send SignalR messages directly from my Azure WebJob to browser clients running on my web-server(s), so I've configured SignalR to use Azure Service Bus as a backplane on both the WebJob and my server. Messages sent from the WebJob are going to the Service Bus topic queues and are being picked up by the web-server but are not being sent on to connected SignalR web clients. I thought this would happen automatically, do I have to somehow subscribe to my WebJob SignalR messages from the web-server and manually propogate them to the browser clients?
I'd paste some code but I'm not sure what's relevant as I'm not receiving any errors. I can track messages from the WebJob through the service bus to my web-server but nothing reaches the SignalR browser clients running on each web-server.
Salient points;
Each Hub instance is registered using the same hub name
The WebJob and the web-server are both using the same Service Bus backplane connection string
I can see that messages are getting sent to the right topic, and the correct subscription is being read
Trace info from the WebJob:
SignalR.ServiceBusMessageBus Information: 0 : Subscribing to 5 topic(s) in the service bus...
SignalR.ServiceBusMessageBus Information: 0 : Creation of a new topic client SIGNALR_TOPIC_SignalREvents_0 completed successfully.
SignalR.ServiceBusMessageBus Information: 0 : Creation of a new subscription 2ea68ce5-58fe-4218-8768-e03675be8e74 for topic SIGNALR_TOPIC_SignalREvents_0 in the service bus completed successfully.
SignalR.ServiceBusMessageBus Information: 0 : Creation of a message receive for subscription entity path SIGNALR_TOPIC_SignalREvents_0/Subscriptions/2ea68ce5-58fe-4218-8768-e03675be8e74 in the service bus completed successfully.
SignalR.ScaleoutMessageBus Information: 0 : Stream(0) - Changed state from Initial to Open
(x5)
SignalR.ServiceBusMessageBus Information: 0 : Subscription to 5 topics in the service bus Topic service completed successfully.
SignalR.ServiceBusMessageBus Verbose: 0 : Sending 68 bytes over Service Bus: {"H":"auctionHub","M":"Init","A":[{"Price":569.72,"Symbol":"GOOG"}]}
SignalR.ServiceBusMessageBus Verbose: 0 : Sending 68 bytes over Service Bus: {"H":"auctionHub","M":"Init","A":[{"Price":577.38,"Symbol":"APPL"}]}
SignalR.ServiceBusMessageBus Verbose: 0 : Receiving 68 bytes over Service Bus: {"H":"auctionHub","M":"Init","A":[{"Price":569.72,"Symbol":"GOOG"}]}
SignalR.ScaleoutMessageBus Information: 0 : OnReceived(4, 65, 1)
Trace from the web-server
SignalR.ServiceBusMessageBus Information: 0 : Subscribing to 5
topic(s) in the service bus... SignalR.ServiceBusMessageBus
Information: 0 : Creation of a new topic client
SIGNALR_TOPIC_SignalREvents_0 completed successfully.
SignalR.ServiceBusMessageBus Information: 0 : Creation of a new
subscription e6afd744-7724-4ab5-8fd9-2717a62caf61 for topic SIGNALR_TOPIC_SignalREvents_0 in the service bus completed successfully. SignalR.ServiceBusMessageBus Information: 0 : Creation of a message receive for subscription entity path SIGNALR_TOPIC_SignalREvents_0/Subscriptions/e6afd744-7724-4ab5-8fd9-2717a62caf61 in the service bus completed successfully.
SignalR.ScaleoutMessageBus Information: 0 : Stream(0) - Changed state from Initial to Open
SignalR.ServiceBusMessageBus Information: 0 : Creation of a new topic
client SIGNALR_TOPIC_SignalREvents_1 completed successfully.
SignalR.ServiceBusMessageBus Information: 0 : Creation of a new
subscription 2c155757-123f-44ba-ace7-96a6b390234e for topic
SIGNALR_TOPIC_SignalREvents_1 in the service bus completed
successfully. SignalR.ServiceBusMessageBus Information: 0 : Creation
of a message receive for subscription entity path
SIGNALR_TOPIC_SignalREvents_1/Subscriptions/2c155757-123f-44ba-ace7-96a6b390234e
in the service bus completed successfully. SignalR.ScaleoutMessageBus
Information: 0 : Stream(1) - Changed state from Initial to Open
SignalR.ServiceBusMessageBus Information: 0 : Creation of a new topic
client SIGNALR_TOPIC_SignalREvents_2 completed successfully.
SignalR.Transports.TransportHeartBeat Information: 0 : Connection
869c61bb-5070-4c64-811a-9a3612eff981 is New.
SignalR.ServiceBusMessageBus Verbose: 0 : Receiving 37 bytes over
Service Bus: {"H":"auctionHub","M":"Init","A":[1]}
SignalR.ScaleoutMessageBus Information: 0 : OnReceived(4, 221, 1)
SignalR service-bus config code (same on WebJob and web-server)
var scaleOutConfig = new ServiceBusScaleoutConfiguration(ConfigurationManager.ConnectionStrings["AzureWebJobsServiceBus"].ConnectionString, "SignalREvents");
GlobalHost.DependencyResolver.UseServiceBus(scaleOutConfig);
If I had any hair left I'd be tearing it out. I've searched this extensively but wasn't able to find anything useful. Any pointers would be greatly appreciated.
Edit >>
[HubName("auctionHub")]
public class AuctionHub : Hub<IAuctionHubClientMethods>
{
private readonly IAuctionHubService _auctionHubService;
public AuctionHub(IAuctionHubService auctionHubService)
{
_auctionHubService = auctionHubService;
}
public override Task OnConnected()
{
var userId = Context.User.Identity.GetUserId();
var connectionId = Context.ConnectionId;
_auctionHubService.OnConnected(Groups, userId, connectionId);
return base.OnConnected();
}
public interface IAuctionHubClientMethods
{
Task Heartbeat(string now);
Task Init(AuctionViewModel eventId);
}
public class AuctionHubService : IAuctionHubService
{
<snip>
public AuctionHubService(IAuctionServices auctionServicesProxy, IQueryProcessor queryProcessor, ApplicationUserManager userManager)
{
<snip>
}
public void OnConnected(IGroupManager groups, string userId, string connectionId)
{
var user = _userManager.FindById(userId);
var client = user.Client;
var id = client?.Id;
groups.Add(connectionId, user.Client.Id.ToString());
}
public void Init(int eventId, IHubCallerConnectionContext<IAuctionHubClientMethods> clients)
{
var query = new GetAuctionViewModelByEventIdQuery { EventId = eventId };
var eventState = _queryProcessor.Process(query);
eventState.Suppliers.ForEach(x => clients.Group(x.SupplierId.ToString()).Init(eventState));
}
}
OnDisconnected and OnReconnected are untouched.
I am using SimpleInjector to supply the SignalR context as needed, would this implementation have any effect?
var hubConfiguration = new HubConfiguration
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = false,
Resolver = new SignalRDependencyResolver(MvcApplication.Container),
};
app.MapSignalR<SignalRHubDispatcher>("/signalr", hubConfiguration);
public class SignalRHubDispatcher : HubDispatcher
{
public SignalRHubDispatcher(Container container, HubConfiguration configuration) : base(configuration)
{
_container = container;
}
protected override Task OnConnected(IRequest request, string connectionId)
{
return Invoke(() => base.OnConnected(request, connectionId));
}
protected override Task OnReceived(IRequest request, string connectionId, string data)
{
return Invoke(() => base.OnReceived(request, connectionId, data));
}
protected override Task OnDisconnected(IRequest request, string connectionId, bool stopCalled)
{
return Invoke(() => base.OnDisconnected(request, connectionId, stopCalled));
}
protected override Task OnReconnected(IRequest request, string connectionId)
{
return Invoke(() => base.OnReconnected(request, connectionId));
}
private async Task Invoke(Func<Task> method)
{
using (_container.BeginExecutionContextScope())
{
await method();
}
}
private readonly Container _container;
}

Payload data or userInfo from push notification when app is in suspended mode or app exit in iOS

I am suffering from an issue. I wanted to get get userInfo or payload data when app is in suspended mode. I am able to get payload data when i tap on received notification. but i am not able to get userInfo data when app is in suspend more exited. Is there any way or method to get push notification data ? when app suspend more exited mode
i am using following method :
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(#"notification active=%#",userInfo);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
flag=0;
if (application.applicationState == UIApplicationStateActive || application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground)
{
NSLog(#"notification active=%#",userInfo);
}
else
{
NSLog(#"notification inactive%#",userInfo);
}
application.applicationIconBadgeNumber = 0;
}

Resources