So I'm trying to send push-notifications to users via Braze, but I'm having problems on IOS.
Problem description
First, I install the app from TestFlight and open it. And I say "yes" to receiving notifications:
The lines of code most responsible for opening this dialogue are here:
import * as Notifications from 'expo-notifications'
...
permissionObj = await Notifications.getPermissionsAsync()
Then the code fetches the push-token:
let token = await Notifications.getDevicePushTokenAsync()
if (token && typeof token === 'object' && token?.data) {
token = token?.data
}
Here is an example of what a token extracted in this way might look like:
e35d1a89c7bb23d1203cc1418def923753ca6fc55c8611d7e1c6351f1424b1ea
(this is in fact a non-altered copy of the last token I extracted)
After having done this, the Braze dashboard for my new test-user will tend to look as follows:
As you can see, it says:
Push Registered For Foreground: ASL Bloom (iOS)
This is what it mostly says at this stage in the process, but sometimes it has said other (but overlapping) things. At times it has said:
Push Registered For Foreground: ASL Bloom (iOS)
Push Registered For Background: ASL Bloom (iOS)
(I haven't detected any clear pattern for when it says one or the other, and I have tried to do all that I know can be done so as to allow for background-notifications)
After having specified the push-token to Braze, I try to send a test-notification from Braze. When I do so, it sometimes works on the first try. But if I do more tries it will tend to fail at the second (and maybe sometimes third) try. And often it doesn't even work on the first try.
I haven't noticed any clear pattern as to whether the app is open or closed the first time it fails.
When a notification from Braze fails, it is coupled with a change to the user dashboard:
Again and again (also when I try new users, new builds, and new app installs) I get:
Received 'BadDeviceToken' sending to [token]
Something noticable is that the token shown on the dashboard isn't the same as what I provide them with.
For example, in this last attempt, what I provided them with was:
e35d1a89c7bb23d1203cc1418def923753ca6fc55c8611d7e1c6351f1424b1ea
(64-character hexidecimal string)
But the token Braze seems to use is:
65333564316138396337626232336431323033636331343138646566393233373533636136666335356338363131643765316336333531663134323462316561
(128-character decimal string)
So the token that I provide to Braze with Braze.registerPushToken is not the token they end up with. At the same time, it does seem like Braze.registerPushToken is the call that causes the dashboard to say...
Push Registered For Foreground: ASL Bloom (iOS)
...and I'm not aware of making any other Braze-call than Braze.registerPushToken from which they could receive a push-token.
I experimented with having "made up test-token" be specified as token, which went as follows:
Braze.registerPushToken("made up test-token") → "6d61646520757020746573742d746f6b656e" on Braze dashboard
This looks different than how things usually looks, suggesting that the token on the Braze dashboard is affected by the specific value I provide through Braze.registerPushToken.
About push-notifications via Braze to our Android-app
They seem to work.
About notifications via scheduling on device (not via Braze) to our IOS-app
Seems to work.
(Although there have been some builds where on my device they did not work. The option to allow notifications for the app were not available from my phone's settings, and the dialogue asking for notifications-permission did not open via the app when it was supposed to be triggered. I didn't perceive any rhyme or reason to this, but the problem went away when installing a later build without me knowing why.)
Some more images
From ios/[projectname]/[projectname].entitlements
From the IOS app-settings on Braze:
I have experimented with switching between "Send to Development Environment" and "Send to Production", but this did not fix things. I think "Send to Production" should be the correct option.
Braze's documentation
In their troubleshooting-guide, Braze's documentation has a section about BadDeviceToken (which is the error I seemingly get):
Let me comment this line by line (often using rhetorical questions, so as to explain my thinking):
"The app received a push token that was invalid for the credentials uploaded to the dashboard."
Why would that be? And why would notifications sometimes reach my IOS phone from Braze (before this quickly stops working)?
"Push was disabled for this workspace."
Why would they be disabled in my workspace specifically? Why do notifications from Braze sometimes work for a quick while? Why do locally scheduled notifications work (both in the background and foreground)?
"The user has opted out of push."
Not the case.
"The app was uninstalled."
Not the case (notifications stop working before I re-install).
"Apple refreshed the push token, which invalidated the old token."
This seems to not be the case. I can see from my app's logs that I keep fetching the same token when calling Notifications.getDevicePushTokenAsync() unless I reinstall the app.
Also, it would be weird for apple to invalidate it so quickly.
"The app was built for a production environment, but the push credentials uploaded to Braze are set for a development environment (or the other way around)."
As mentioned, I have experimented with changing this setting in the Braze app settings, and it didn't help.
Also, if I had wrong setting, why would things sometimes work for a short while before they quickly stop working?
Summary
- Android-notifications work (sent via Braze or otherwise). On IOS locally sheduled notifications work, but push-notifications from Braze do not.
- Push notifications sent from IOS to Braze sometimes work for a short while after a token has been set, but then stop working very quickly (without user action between when they work and when they stop working). While sometimes they don't work from the get-go.
- The push key shown value on the Braze dashboard doesn't match what I send via Braze.registerPushToken, but me calling Braze.registerPushToken is why there is a value that is added there at all, and which value I add affects what value is added to the Braze dashboard (so it seems the value is transformed somehow).
Any help with this would be greatly appreciated!
Looks like background push is present as default.
https://www.braze.com/resources/articles/the-technical-side-of-push-notifications