Closed marstr closed 4 years ago
I am having this same issue. I am using the AppleTemplateRegistrationDescription to register my template with Azure. I set the ApnsHeaders for my silent/background push to the following per this article's recommendations:
template.ApnsHeaders.Add("apns-push-type","background");
template.ApnsHeaders.Add("apns-topic","com.company.AppNameHere");
template.ApnsHeaders.Add("apns-priority","5");
Even with registering with these settings, the background pushes do not get received by the device. If I include no ApnsHeaders, I get the same result. Alerts appear to be working just fine. Any help would be appreciated as this is breaking functionality of our application on iOS 13. Thanks!
Howdy folks, we've found some server side logic that was getting in the way of including these headers. We're working on a fix, and will update this thread when we have deployed the changes.
From azure support, the headers don't need to be on the installation registration but on the actual sending of the push message: var backgroundHeaders = new Dictionary<string, string> { { "apns-push-type", "background" }, { "apns-priority", "5" } }; Dictionary<string, string> templateParams = new Dictionary<string, string>(); // populated templateParams according to our logic
var notification = new TemplateNotification(templateParams); notification.Headers = backgroundHeaders; // the second parameter is the tag name and the template name as we have it registered from the device. var resBack = await hubClient.SendNotificationAsync(notification, tags);
Also the push hub needs to be configured with a key not a certificate to support it. I have yet to test this, but thought I would share it.
Cheers
@gretgjoka Interesting... Mine started working today randomly. I figured the people at Azure had something to do with it. I included the headers on the template registration, not on the sending, and it still worked. Hope it's fixed for everyone. Thanks all!
As an update, I just tested and mine are still not working.
I tested as well, not working on my side either with the changes I posted above
@AntRemo @gertgjoka Did you all try adding the APNS headers to the template registration as I did? It is worth a shot if you have not.
template.ApnsHeaders.Add("apns-push-type","background");
template.ApnsHeaders.Add("apns-topic","com.company.AppNameHere");
template.ApnsHeaders.Add("apns-priority","5");
@milettal I am using the installation method with templates, in the API i get an Installation object from the device, and it contains a list of InstallationTemplate which only has a header property. Where would the ApnsHeaders be?
@gertgjoka Ah, I am probably using a different method than you. I am using the "Microsoft.Azure.NotificationHubs" nuget package for .NET (the GitHub we're on). With that, you can specify the Apns headers. My code looks like this:
AppleTemplateRegistrationDescription template = new AppleTemplateRegistrationDescription(deviceTokenStr);
template.Tags = new HashSet<string> { "Tag1","Tag2" };
template.ApnsHeaders=new ApnsHeaderCollection();
template.ApnsHeaders.Add("apns-push-type","background");
template.ApnsHeaders.Add("apns-topic","com.company.app");
template.ApnsHeaders.Add("apns-priority","5");
template.TemplateName = "templateName";
template.BodyTemplate = "Put JSON here with content-available: 1";
await client.CreateRegistrationAsync(template);
Hi @milettal
Thanks for your suggestion. You are correct, I at least, am using a different method.
I am using the InstallationTemplate class with the following APNS template
{ "aps": { "content-available": 1, "DataMessage": "$(DataMessage)" } }
This is then assigned to the Installation class which has a Templates Dictionary for InstallationTemplates.
After that is setup I call hubClient.CreateOrUpdateInstallation
@AntRemo @gertgjoka Ah, I was unaware of the InstallationTemplate method of registering for templates. It's odd to me that this is the recommended method from Azure but you are not able to specify APNS headers... Would switching to the Registration method break your push infrastructure?
@marstr Is there any way for people using the InstallationTemplate method to set any APNS headers to be passed to Apple?
Hi @marstr
Just wanted to check-in and see if there was any time-frame when this issue may be resolved.
Thanks๐
@milettal says: @marstr Is there any way for people using the InstallationTemplate method to set any APNS headers to be passed to Apple?
Not as far as I'm aware, but I'm still fairly new to the team.
@AntRemo says: Just wanted to check-in and see if there was any time-frame when this issue may be resolved.
I'm afraid I don't have much status to share! We're still in the process of rolling out our fix.
@marstr I understand and thanks for the update :)
Updating our logic to match @milettal notes above did not change the behavior. We see the device notification, and even using the Azure Tool have been unable to get a successful background push received in the app. This was working prior to the change.
@marstr Any update on deploying a resolution to the issue?
Also waiting for an update on this?
seriously waiting for an update on this.
We have our two environments, having exactly the same code, but using their respective notifications hubs.
on environment A, the behaviour is not consistent. The devices (iPhone, iPad) don't receive push notifications all the time.
on environment B, it's a total outage. No push notifications are received.
Howdy folks, I've just confirmed that we've finished rolling out our changes to infer the apns-push-type
header value globally. Furthermore, I can confirm that we're seeing the expected behavior on our side. Please confirm whether or not you are still impacted.
However, there are still issues at play that may be preventing your notifications from going through! For instance, make sure that you're setting the apns-priority
header appropriately as documented by Apple: Sending Notification Requests to APNs
As I hear back from you on whether or not you're still impacted, I will split out any related issues into their own issues as appropriate.
@neil445 if you believe Notification Hubs isn't delivering your notifications, please reach-out to Azure Support to begin an investigation.
@anthonyplews @AntRemo @gertgjoka @JohnBergman @milettal @neil445
@marstr Thanks for the great news. Would you mind telling us where specifically to set these headers?Azure support told us to set those when sending each push message, while here we saw users setting those during the device registration with Azure Hub. Thank you!
I just tried now setting headers in both sending of the push and registration, none of the tests worked for background push...
I still observe the issue as well. Tried to update my code last week to explicitly include apns-push-type but even with that, the background notifications do not seem to work.
var notification = new AppleNotification(@"
{
""aps"": {
""content-available"": 1
}
}")
{
Priority = 5
};
notification.Headers["apns-push-type"] = "background";
@milettal says: Is there any way for people using the InstallationTemplate method to set any APNS headers to be passed to Apple?
I've just verified that I'm receiving the expected Notifications on iOS 13 with the following code using Installation Templates and set headers:
private static async Task<string> SendAfterTemplateInstallation(NotificationHubClient nhClient, string deviceToken)
{
var parity = Guid.NewGuid();
var installTemplate = new InstallationTemplate()
{
Body = $"{{\"aps\":{{\"alert\":\"Notification Hub test notification with secret {parity.ToString()}\"}}}}",
// Worth noting, I'm seeing success with and without the Headers being set below.
Headers = new Dictionary<string, string>
{
{"apns-push-type", "alert"},
{"apns-priority", "10"},
},
};
var randomTag = Guid.NewGuid();
var myTags = new[] { randomTag.ToString()};
var installationId = Guid.NewGuid().ToString();
var myInstallation = new Installation
{
InstallationId = installationId,
Tags = myTags,
Platform = NotificationPlatform.Apns,
PushChannel = deviceToken,
Templates = new Dictionary<string, InstallationTemplate>
{
{"myTemplate", installTemplate}
}
};
await nhClient.CreateOrUpdateInstallationAsync(myInstallation);
Console.WriteLine($"Installation Created with secret {parity}");
// When I don't delay, this doesn't work. It does take some time for the system to complete
// an installation after it's been requested. I haven't tried pushing those limits
for (var i = 15; i > 0; i--)
{
Console.WriteLine(i);
await Task.Delay(TimeSpan.FromSeconds(1));
}
var result = await nhClient.SendTemplateNotificationAsync(new Dictionary<string, string>(), myTags);
return result.TrackingId;
}
@gertgjoka, I think the above should work for you as well. @ostastny, I suspect your issue is unrelated. Make sure you have your hands on the correct Device Token, have configured your APNS credentials correctly.
@marstr Your example refers to an alert notification, we are all instead saying that we don't receive background notifications, so with apns-push-type: "background", priority 5 and and content-available: 1. Can you please let us know?
@marstr
I too can confirm that setting the InstallationTemplate.Headers as follows does not appear to have any affect.
installationTemplate.Headers = new ApnsHeaderCollection()
{
{"apns-push-type", "background"},
{"apns-priority","5" }
};
I also reinstalled the app on my phone, just to be sure there was not an issue with the existing installation.
@AntRemo, in the other thread you were reporting that the you got the following error message when setting the Headers property of an InstallationTemplate:
Template 'hello is invalid: 'Headers' only acceptable for WNS and MPNS...
Are you still encountering that?
@marstr
Correct. However, now I do not receive an error message and it appears to upload properly.
Please let me know if you would like me to add some query logic to verify it is being uploaded properly to Notification Hubs.
@marstr To answer your comment, I don't believe my issue is related Device Tokens. I can successfully receive alert notifications on my test devices, it's only background notifications that don't work. Actually, had some users report they saw some background notifications come through but even for those users the delivery success rate would be very low (one in ten or less...)
Howdy folks, we're still working on repro'ing this problem. To help us get to the bottom of it, would you mind confirming which version of iOS 13 you're using?
@AntRemo @gertgjoka @JohnBergman @neil445 @ostastny
13.1.2
13.1.2
13.1.2
Was 13.1.2 now 13.1.3
I was just wondering what is your app development platform guys? We are using cordova and phonegap-push-plugin. Thanks! @AntRemo @neil445 @ostastny @anthonyplews
Okay so managed to get everything working:
Backend API (.net core 2.2):
Update Device Registration method on API to convert handle to hex string:
public async Task<DeviceRegistration> Register(string handle = null)
{
handle = ToHexString(handle);
string newRegistrationId = null;
if (handle != null)
{
var registrations = await _Hub.GetRegistrationsByChannelAsync(handle, 100);
foreach (RegistrationDescription registration in registrations)
{
if (newRegistrationId == null)
{
newRegistrationId = registration.RegistrationId;
}
else
{
await _Hub.DeleteRegistrationAsync(registration);
}
}
}
if (newRegistrationId == null)
{
newRegistrationId = await _Hub.CreateRegistrationIdAsync();
}
var deviceRegistration = new DeviceRegistration
{
RegistrationId = newRegistrationId
};
return deviceRegistration;
}
public async Task<DeviceRegistration> UpdateRegistration(DeviceRegistration deviceUpdate, string registrationId, string[] tags)
{
RegistrationDescription registration;
switch (deviceUpdate.Platform)
{
case "mpns":
registration = new MpnsRegistrationDescription(deviceUpdate.Handle);
break;
case "wns":
registration = new WindowsRegistrationDescription(deviceUpdate.Handle);
break;
case "apns":
registration = new AppleRegistrationDescription(deviceUpdate.Handle);
break;
case "gcm":
registration = new FcmRegistrationDescription(deviceUpdate.Handle);
break;
default:
throw new Exception("Bad Request");
}
registration.RegistrationId = registrationId;
registration.Tags = new HashSet<string>(tags);
await _Hub.CreateOrUpdateRegistrationAsync(registration);
return deviceUpdate;
}
private static string ToHexString(string str)
{
var sb = new StringBuilder();
var bytes = Encoding.Unicode.GetBytes(str);
foreach (var t in bytes)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString();
}
Mobile App (Ionic 3 Cordova): update phonegap-plugin-push to latest version: 2.3.0.
Mobile App (Ionic 4 Capacitor) We didn't have to do anything it worked after the backend API was updated.
Hope this helps!
@anthonyplews with the latest plugin, the handle is already in the right format. I had updated it already, and I am receiving alert push notifications, but not receiving the silent/background ones. Were you receiving anything prior to this change?
@gertgjoka I wasn't receiving any backend notifications prior to this change, this is a snippet of the code we use for iOS backend notifications:
var iMsg = JsonConvert.SerializeObject(iosMessage);
outcome = await _Hub.SendAppleNativeNotificationAsync(iMsg, tags);
@anthonyplews your issue was different from ours then. All of us have issues with background notifications (those with "content-available": 1). Can you receive those? How is your hub configured, with a certificate or a key?
@gertgjoka we configured a certificate.
I see your issue now, as you can see from our code we pass through a json payload and don't specify the apns-priority so it defaults to 10:
We haven't tested with "content-available": 1
Hi @gertgjoka
I am using Xamarin.
I was able to find a workaround for now, add the badge:0 to the apns payload for silent push and also make sure to remove the headers you may send from .net code during the push send (those were blocking the push for me). I can now finally receive a silent push @AntRemo @neil445 @ostastny @anthonyplews
The side effect of it is that setting the badge to 0 will clear the visible/alert push messages that were there before it. Might not be an acceptable solution for everybody.
@gertgjoka Thanks for the update.
That will not be an option for our scenario.
Hope it has provided some relief for you.
Hi @marstr
Just wanted to check the status.
It is has been 8 weeks since the original issue was reported and this is beginning to be a real problem for us.
Many thanks ๐
Howdy @AntRemo,
Your frustration is understood! The original problem was that InstallationTemplates targeting APNs with any Headers were blocked by some of our server side validation. We've since deployed a fix for that, and have validated that we're passing the appropriate headers through our system.
Since that fix, we're still hearing from some folks on this thread that background notifications are not being delivered to their applications. We're taking that seriously, and have traced through our system to make sure that we're delivering notifications to Apple in the format we had expected. At the moment, we believe we are delivering notifications as appropriate. However, we're still in the process of doing due diligence before we can make any conclusions about the behavior reported here.
Sorry for the inconvenience!
@marstr
I have great news. I managed to get notifications to work without changing any server side code.
To be clear, I did not need to add the following to my server side.
installationTemplate.Headers = new ApnsHeaderCollection()
{
{"apns-push-type", "background"},
{"apns-priority","5" }
};
I stumbled across the following doc titled Azure Notification Hubs updates for iOS 13 which states
Developers must now set this header in applications that send notifications through Azure Notification Hubs. Due to a technical limitation, customers must use token-based authentication for APNS credentials with requests that include this attribute. If you are using certificate-based authentication for your APNS credentials, you must switch to using token-based authentication.
Because I have been using Notifications Hubs for years, I had it setup to use certificate-based authentication.
After changing it to token-based authentication following this document Token-based (HTTP/2) Authentication for APNS It worked! Also because no code changed, I was able to update and confirm production is working without doing a deployment.
Question
Should I add the code above to set the headers or is that an optional step because I am setting "content-available": 1
in the payload?
Note for others attempting to switch from certificate to token: It took me a few mins to figure out what the token was obtained. I simply had to open the .p8 file I downloaded and extract the characters between the -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- and paste that into the Token field.
@AntRemo I have mentioned on my October 3rd comment that you need a token according to what Azure support told me, but it didn't solve the issue for silent push notifications on my case. Can you please confirm if you are now receiving background/silent push notifications?
@gertgjoka I must have missed that. ๐๐
I can 100% confirm it is working for me now, with no changes to server code.
The only change I made to my app, a month ago, was updating the way that the device token is extracted for iOS 13
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
...
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
// New for iOS 13
byte[] result = new byte[deviceToken.Length];
Marshal.Copy(deviceToken.Bytes, result, 0, (int)deviceToken.Length);
pushChannel = BitConverter.ToString(result).Replace("-", "");
}
else
{
// Prior to iOS 13
pushChannel = deviceToken.Description.Trim('<').Trim('>').Replace(" ", "");
}
...
}
It may be worth double checking the Notification Hub settings on the Azure portal.
Please let me know if you have any other questions.
Good Luck! Ant
Hi Guys! I am a Xamarin developer and following this thread for a while. I managed to receive silent push notifications on my ios app but I see some strange behavior as follows;
I am not using any apns headers instead, I am just using payload for sending silent push.
@marstr @gertgjoka @AntRemo @anthonyplews @neil445 @ostastny can you pls confirm are you able to see this behavior on your side as well?
or is there anything that I am missing from my side?
Hi @RajGogri
I just tested scenario #4 by simply swiping home and it worked properly.
I then performed the same scenario, but then opened another app and it did not appear to immediately deliver the notification to the app.
Having said that, I'm not sure if this is the normal behavior for iOS. If an app is both in the background and another app is in the foreground, it may throttle the background notification delivery speed.
Hope that helps.
Thanks @AntRemo for quick response. I tested in the way u suggested by swiping home, but unfortunately no signs of receipt of silent push for me. Did you performed your test by connecting to cellular network ? I asked that because for me silent apns push works fine when phone is connected to wifi and app is in background.
Also now i have changed my backend code to send required apns headers along with payload in azure notification hub using AppleNotification class. But still no success. ๐
On my further testing what I found is; The issue mentioned in point 4 https://github.com/Azure/azure-notificationhubs-dotnet/issues/96#issuecomment-549255469 here doesnโt occur on pre iOS 13 devices.
So basically, Silent Apns Push is not working for me when app is in background and connected to cellular network on iOS 13 devices.
Need assistance!!!
Multiple customers are reporting that they are unable to include headers to indicate the
apns-push-type
when using templates.More conversation can be found here: https://github.com/Azure/azure-notificationhubs-dotnet/issues/88#issuecomment-537047099