简体   繁体   中英

Register again a device with some tags to a azure notification hub using Xamarin

I'm following a series of tutorials to create a Push Notifications Xamarin app , particularly for Android, to receive notification through Azure notification hub and Firebase . This is the 1st video and the code is here in github . But I need to choose the moment when the app registers the device into the notification hub with the tag. Currently, it happens in OnNewToken , but I need to let the user log on first, or provide tags by input and only then I would have the tags to register with.

Solution/Project.Android/Model/FirebaseMessagingServiceEx.cs

public override void OnNewToken(string token)
{
    base.OnNewToken(token);

    System.Diagnostics.Debug.WriteLine(token);

    var hub = new NotificationHub(
        Constants.HubName,
        Constants.HubConnectionString,
        MainActivity.Context);

    // register device with Azure Notification Hub using the token from FCM
    var registration = hub.Register(token, Constants.HubTagName);

    // Register template
    var pnsHandle = registration.PNSHandle;
    var templateReg = hub.RegisterTemplate(
        pnsHandle,
        "defaultTemplate",
        Template,
        Constants.HubTagName);

    var receiver = DependencyService.Get<INotificationsReceiver>();
    receiver.RaiseNotificationReceived("Ready and registered...");
}

I don't even understand when OnNewToken is invoked! I tried to force the generation of another token to run OnNewToken again… unsuccessfully. Can I retrieve the current token to perform hub.Register at a later time after retrieving the user tags? All the examples I saw, were using deprecated code. Are there other alternatives? Thanks.

Unfortunately the push notification documentation for Xamarin is quite fractured and a lot of it is deprecated/outdated. I struggled for some time finding the most current mechanism for getting the device token and registering with Azure Notification Hubs.

To get the device token, you should not be overriding OnNewToken. The current preferred mechanism is the following:

  1. In your Android project, create a C# class that implements Android.Gms.Tasks.IOnCompleteListener :
/// <summary>
/// Wraps the native Android interface <see cref="IOnCompleteListener"/>,
/// which enables interaction with Promise-style async callbacks.
/// </summary>
public class GetFcmTokenSuccessHandler : Java.Lang.Object, IOnCompleteListener
{
    private readonly Action<string> _handleFcmTokenCallback;

    public GetFcmTokenSuccessHandler(Action<string> handleFcmTokenCallback)
    {
        _handleFcmTokenCallback = handleFcmTokenCallback;
    }

    /// <summary>
    /// Method invoked when the associated <see cref="Task"/> completes.
    /// </summary>
    /// <param name="result">The task that completed.</param>
    public void OnComplete(Task result)
    {
        if (result.IsComplete && result.IsSuccessful)
        {
            var token = result.Result.ToString();

            _handleFcmTokenCallback?.Invoke(token);
        }
        else if (result.IsComplete && result.Exception != null)
        {
            // Add error handling here
        }
    }

    #region Interface requiresments; irrelevant to implementation
    public JniManagedPeerStates JniManagedPeerState => JniManagedPeerStates.None;

    public void SetJniIdentityHashCode(int value) { }
    public void SetJniManagedPeerState(JniManagedPeerStates value) { }
    public void SetPeerReference(JniObjectReference reference) { }
    #endregion
}
  1. After logging in, trigger the following code in a dependency-injected platform-specific service also from your Android project:
await FirebaseMessaging.Instance
    .GetToken()
    .AddOnCompleteListener(new GetFcmTokenSuccessHandler(token =>
    {
        if (string.IsNullOrWhiteSpace(token))
        {
            // Add error handling here
        }

        // Now create your NotificationHub and register with the token and any tags
    }));

As an addendum, if at any point while the app is running you need to register again, I'd recommend caching the device token in memory so you can retrieve it again without going through the FirebaseMessaging instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM