CrossFirebasePushNotification.Current.Subscribe("all") not working on IOS
🐛 Bug Report
On iOS, CrossFirebasePushNotification.Current.Subscribe("all") does not subscribe the phone to the topic "all".
Subscribed topics are not added to the SubscribedTopics list. Notifications sent to topics are not received.
Notifications to tokens on iOS work as expected.
It works fine on Android.
Expected behavior
Reproduction steps
CrossFirebasePushNotification.Current.Subscribe("all"); var subList = CrossFirebasePushNotification.Current.SubscribedTopics; Debug.WriteLine($"sub count: {newList.Length}"); for (int i= 0; i < subList.Length; i++) { Debug.WriteLine($"Subscribed to: {subList[i]}"); }
Configuration
iOS 13.6.1
Plugin.FirebasePushNotification 3.3.10
Version: 1.x 3.3.10 Platform:
- [x ] :iphone: iOS
- [ ] :robot: Android
- [ ] :checkered_flag: WPF
- [ ] :earth_americas: UWP
- [ ] :apple: MacOS
- [ ] :tv: tvOS
- [x ] :monkey: Xamarin.Forms
use "general "
Any keyword "all", "general", "announcement" is working when Subscribe method is called after user permission in iOS.
Appdelegate.cs
using FCMTest.Constants;
using Foundation;
using Plugin.FirebasePushNotification;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UIKit;
using Xamarin.Forms;
namespace FCMTest.iOS
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
// Firebase Cloud Messaging
FirebasePushNotificationManager.Initialize(options, true);
FirebasePushNotificationManager.CurrentNotificationPresentationOption = UserNotifications.UNNotificationPresentationOptions.Alert | UserNotifications.UNNotificationPresentationOptions.Badge | UserNotifications.UNNotificationPresentationOptions.Banner | UserNotifications.UNNotificationPresentationOptions.Sound;
if (options != null)
{
// When app is killed and user tap on Notification then this "options" will execute
NSDictionary notificationObject = (NSDictionary)options["UIApplicationLaunchOptionsRemoteNotificationKey"];
_ = SendNotificationDataAfterAppLaunchFinished(Notification.Parse(Convert(notificationObject)));
}
return base.FinishedLaunching(app, options);
}
/// <summary>
/// RegisteredForRemoteNotifications exucute when user grant permission, a device token is genrated and registered on Firebase
/// for Push Notification
/// </summary>
/// <param name="application"></param>
/// <param name="deviceToken"></param>
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
#if DEBUG
FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken, FirebaseTokenType.Sandbox);
#else
FirebasePushNotificationManager.DidRegisterRemoteNotifications(deviceToken, FirebaseTokenType.Production);
#endif
_ = NotifyPermissionForNotification(true);
}
/// <summary>
/// FailedToRegisterForRemoteNotifications will execute if user delcine permission for notification
/// </summary>
/// <param name="application"></param>
/// <param name="error"></param>
public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
{
base.FailedToRegisterForRemoteNotifications(application, error);
FirebasePushNotificationManager.RemoteNotificationRegistrationFailed(error);
_ = NotifyPermissionForNotification(false);
}
// 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)
{
// 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.
// If you disable method swizzling, you'll need to call this method.
// This lets FCM track message delivery and analytics, which is performed
// automatically with method swizzling enabled.
FirebasePushNotificationManager.DidReceiveMessage(userInfo);
// handle the notification data
completionHandler(UIBackgroundFetchResult.NewData);
}
private async Task NotifyPermissionForNotification(bool permissionGranted)
{
var delayTask = Task.Delay(2000);
MessagingCenter.Send(permissionGranted ? "1" : "0", NotificationTopics.USER_PERMISSION);
await delayTask;
}
}
}
I'm working with shell AppShell.cs
using FCMTest.Constants;
using Plugin.FirebasePushNotification;
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace FCMTest
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class AppShell : Shell
{
public AppShell()
{
// Permission Value for iOS
MessagingCenter.Subscribe<string>(this, NotificationTopics.USER_PERMISSION, (permission) =>
{
// Tells whether user has granted permision for Notification
_notificationService.UserPermission = permission == "1";
if (permission.Equals("1"))
{
CrossFirebasePushNotification.Current.Subscribe("all");
}
});
FCMInitiateOnStart();
}
private void FCMInitiateOnStart()
{
// subscribe to tpoic
if (Device.RuntimePlatform == Device.Android)
{
CrossFirebasePushNotification.Current.Subscribe("all");
}
}
}
}