Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent badge count #57

Closed
zenangst opened this issue Aug 17, 2016 · 34 comments
Closed

Inconsistent badge count #57

zenangst opened this issue Aug 17, 2016 · 34 comments

Comments

@zenangst
Copy link

zenangst commented Aug 17, 2016

Ohai,

We are having some issues with keeping the badge counter in sync with the application content. We have disabled the clearing of the badge counter using OneSignal_disable_badge_clearing in our application plist. This solves one part of the problem, now it will keep the correct badge count when you open and leave the application.

The problem arises when we get a new push notification that updates the badge count
using Increment. It always defaults back to 1 the first time, then it starts incrementing the value as expected, as in 1, 2. As soon as you re-enter the application it will then use the application data to set the application badge counter again which is correct but when you receive another push notification you are back to step 1 and value 1.

We tried to manually set the badge count for the player using the API but that
doesn't seem to have any positive effect (the response comes back as 200 successful).

The thing we are trying to achieve is more of a Mail approach, that the badge counter represents the unread content and not how many notifications that you haven't seen yet.

We contacted support and got some short tid-bits that we could achieve this behavior with OneSignal_disable_badge_clearing enabled so we tried to enable the badge clearing again but we ended up with the same result as with it the badge clearing disabled.

When we used Parse, we achieved this behavior by updating the current installation;

This is what we used with Parse;

PFInstallation.currentInstallation().badge = count
PFInstallation.currentInstallation().saveInBackground()

We thought we could do the same by manually sending a request to players/:id and setting the badge count to the value that the application has.

As seen in OneSignalTracker.m
https://github.com/OneSignal/OneSignal-iOS-SDK/blob/master/iOS_SDK/OneSignalTracker.m#L106-L116

        NSMutableURLRequest* request = [httpClient requestWithMethod:@"PUT" path:[NSString stringWithFormat:@"players/%@", [OneSignal mUserId]]];

        NSDictionary* dataDic = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [OneSignal app_id], @"app_id",
                                 @0, @"badge_count",
                                 nil];

        NSData* postData = [NSJSONSerialization dataWithJSONObject:dataDic options:0 error:nil];
        [request setHTTPBody:postData];

        [OneSignalHelper enqueueRequest:request onSuccess:nil onFailure:nil];

Any ideas on how to solve this?

@zenangst
Copy link
Author

Small update on this, seems like we forgot one important thing when sending the request to OneSignal. We didn't set the correct HTTPMethod when doing the request but we still got a 200, it kinda rendered a false positive for us.

So with OneSignal_disable_badge_clearing enabled and a proper request when we update our own badge we were able to achieve the behavior that we wanted.

However, this required some work in our client and if would be super nifty if one convenience method was added to the public API to be able to post this kind of request to OneSignal.

I can gladly make a PR for this if you think it holds value for others.

@zenangst zenangst changed the title Inconsistent badge count Inconsistent badge count [SOLVED] Aug 17, 2016
@zenangst
Copy link
Author

Feel free to close this one when you guys get to it but do consider my last comment about the feature being added to the public API.

Cheers! 🍻

@JKalash
Copy link
Contributor

JKalash commented Aug 17, 2016

Hi,

Thank you for providing this feedback. We will look into solving this inconvenience on a future update of our SDK.

@sidan5
Copy link

sidan5 commented Nov 29, 2016

OneSignal_disable_badge_clearing is the only way that worked for us when using Parse iOS SDK with OneSignal.
This should be fixed.

@jkasten2
Copy link
Member

jkasten2 commented Apr 28, 2017

@zenangst @sidan5 Update on this issue. We considering on using a NotificationServiceExtension since it is already in place as part of our SDK setup to handle the increase badge count feature. It could use a custom key send from OneSignal in aps payload and add it to [UIApplication sharedApplication].applicationIconBadgeNumber when the notification is received. This would save extra network calls needed to sync this value and would prevent any possibly of values getting out of sync.

@zenangst Sorry about overlooking your request to help with a PR on this. Let me know what your thoughts are on the above implantation. I estimate I won't have time to implement this until after May. If you want to take a crack this implementation let me know and I'll provide any guidance I can. Or I'll let you know before I start working on this so we don't overlay.

@jkasten2 jkasten2 reopened this Apr 28, 2017
@jkasten2 jkasten2 changed the title Inconsistent badge count [SOLVED] Inconsistent badge count Apr 28, 2017
@rgoldiez
Copy link

@zenangst - I'm running into a similar issue since switching over to OneSignal. I'm trying to achieve the same effect as you, and I've set the flag in my info.plist so that the badge is not cleared. However, opening the app seems to clear the count kept on the OneSignal server side. When I query my badge count using curl from terminal, I can see may server side badge count change about a second after opening my app.

Are you manually setting the badge count on the OneSignal server when you open your app?

Side note.... I'm not sure the scenario when OneSignal_disable_badge_clearing is set but you want to clear the count on the OneSignal server.

@zenangst
Copy link
Author

@rgoldiez hey man, we never solved this is a good way so we decided to step away from OneSignal and use our own parse server.

@rgoldiez
Copy link

@zenangst - Thanks for the feedback. Been fighting with it for a couple months now thinking it was something I was doing with my app implementation.

@jkasten2
Copy link
Member

jkasten2 commented Jun 29, 2017

@rgoldiez Sorry to hear, we still plan to implement the NotificationServiceExtension solution but can't say when it will be ready.

@zenangst @rgoldiez To summarize and confirm the current issue, the badge Increment feature does not work correctly when the badge count is changed outside of OneSignal (local or remote). OneSignal_disable_badge_clearing does not resolve the issue either in this case.

@rgoldiez
Copy link

@JKalash - I wouldn't describe my issue as a problem with the Increment feature, but Increment seems to expose as issue with the iOS SDK. Even with OneSignal_disable_badge_clearing set, opening the app resets the count for that player on OneSignal's servers. I can verify that with a curl request for that player ID and see it go from badge_count: [x] to zero moments after I open the app.

My setup is like @zenangst ... I am managing my "unread" counts on my own server. If a message is intended for multiple recipients, a POST is sent to OneSignal with an array of player IDs and Increment. When a given user/client views a specific message(s), I mark that on my server and "set" their badge count on the OneSignal to the now current unread count.

Everything works fine except that when the app is opened, the OneSignal server gets reset to 0. The user's iOS badge count remains unchanged (with OneSignal_disable_badge_clearing set), but the next push notification from OneSignal sets the badge count to 1 (because it was reset on the server to 0).

I guess what I'm wondering is why would OneSignal_disable_badge_clearing also not clear the count on OneSignal?

@jkasten2
Copy link
Member

@zenangst The Increment feature works by tracking the current count server side, since iOS doesn't support increment nativity. The reset your seeing is due to the badge being set to 0 the OneSignal server when the OneSignal SDK calls the on_session to when the app is open. The OneSignal_disable_badge_clearing does not effect any REST API calls which is way the de-sync is happening.

@rgoldiez
Copy link

@jkasten2 - Are you saying this is the intended behavior or just explain what's going on? Does this need to wait for the NotificationServiceExtension to get "fixed"?

@jkasten2
Copy link
Member

jkasten2 commented Jun 29, 2017

@zenangst This is current behavior, to prevent this issue or any other de-sync scenarios, increments should be handled client side. Using a NotificationServiceExtension would be the correct way to handle it.

It could be done today by adding your own logic to one in your app and including your increment value as additional data so it can be read from the payload. By setting bestAttemptContent.badge in the didReceiveNotificationRequest:withContentHandler: selector.
https://documentation.onesignal.com/docs/ios-sdk-setup#section-1-add-notification-service-extension-recommend-
You will also need to enable mutable_content on each notification so the service extension is activated when it is received.
This way our schedule won't be hold you up.

@mlight3
Copy link

mlight3 commented Jul 24, 2017

@jkasten2 I implemented NotificationServiceExtension but I couldn't set correct badge count. I need two value, current badge count and increase value. As you say I sent a increase value as additional data, but I can not calculate bestAttemptContent.badge cause there is no value for current badge count. How can I fix it?

@jkasten2
Copy link
Member

@mlight3 Normally you can use UIApplication.applicationIconBadgeNumber to get the badge value however it is not possible to access the UIApplication class from App Extension targets.

You will need to store the current value of the badge each time it is changed. I recommend using NSUserDefaults for this. Make sure you set / update this value from your app as well each time from the NotificationServiceExtension when a badge increment or set is used.

@mlight3
Copy link

mlight3 commented Jul 26, 2017

@jkasten2 I tried as your comment. It works well when app is not focused.
But when the app is focused, notification?.payload.badge is not mutated. :(
I tested with kOSSettingsKeyInAppAlerts=true, title and subtitle also is not mutated.

Here is my codes.

// Notification Service Extension
if let bestAttemptContent = bestAttemptContent {
  if let defaults = UserDefaults(suiteName: NotificationService.userDefaultSuiteName) {
    var badge = bestAttemptContent.badge?.intValue ?? 0
    badge += defaults.integer(forKey: "notificationBadge")
    bestAttemptContent.badge = NSNumber(value: badge)
  }
  OneSignal.didReceiveNotificationExtensionRequest(request, with: self.bestAttemptContent)
  contentHandler(bestAttemptContent)
}
OneSignal.initWithLaunchOptions(
  launchOptions,
  appId: "-",
  handleNotificationReceived: { (notification) in
    self.updateBadge(with: notification)
  },
  handleNotificationAction: { (result) in
    self.updateBadge(with: result?.notification)
  },
   settings: [kOSSettingsKeyAutoPrompt : false, kOSSettingsKeyInAppAlerts : false])

      ...

private func updateBadge(with notification: OSNotification?) {
    UIApplication.shared.applicationIconBadgeNumber = Int(notification?.payload.badge ?? 0)  // <- here
    userDefaultsService.setNotificationBadge(UIApplication.shared.applicationIconBadgeNumber)
  }

@mlight3
Copy link

mlight3 commented Aug 1, 2017

Solve it myself with SetTo and badgeCount = 1

When I am using Increment with badgeCount = 1 and app is focused(means foreground), OneSignal sometimes send different badgeCount to APNS.
It occurred when I send multiple Increment notifications. In handleNotificationReceived callback
sometimes badgeCount is 3 or 2 not 1.

I think OneSignal SDK updated that notification is opened when client received notification. But notification is async, updating notification is slow than new notifications.

I solved it with SetTo and badgeCount = 1. In client, just add 1 then save it UserDefaults.

Hope OneSignal REST API provide sending multiple notifications with individual badge counts.

@jlomelino
Copy link

@mlight3 could you post your code that was changed to make this work? This is something I have been struggling with as well and it looks like you have made some progress. I am not sure if this has been fixed in the API yet or not as some of these comments are older. Yours was newer so I thought I would reach out and ask.

Thanks!

@timacdonald
Copy link

Is there any movement on this one? Definitely seems to still be occurring.

@Nightsd01
Copy link
Contributor

There is movement - we just implemented it yesterday in the iOS SDK. More time is needed for testing and backend changes however. But it should be ready some time soon.

@timacdonald
Copy link

Fantastic, thanks @Nightsd01

@acambridge
Copy link

Thanks, I am following this - we are seeing issues with inconsistent badge counts but also notifications being marked as read (so no longer available to view) when there are multiple to view, and the user opens only one (brings the app to the foreground).

@razvanifteme
Copy link

razvanifteme commented Apr 4, 2018

Hi guys. Did anyone manage to solve the inconsistent badge count on his application ?

I managed to update the badge as wanted, the only thing that ain't working for me, is when the application gets killed. I receive the notification, but the badge does not get updated.

@jkasten2
Copy link
Member

jkasten2 commented Apr 4, 2018

@razvanifteme Notification displaying and badge values are set directly by iOS it self without running any code in your app. The only time you should see the badge not being set is if the notification was received while your app was in focus as the OneSignal SDK will clear badges when the app is in focus. Or if you have any of your own code setting the badge on notification receive or focus events.

@Nightsd01
Copy link
Contributor

@razvanifteme in addition to what jkasten2 said, it could also be an issue with the actual push notifications you are sending. Are you sending them with the REST API? Or are you sending them using the OneSignal dashboard?

Also - I would recommend checking your entire project for any usage of setApplicationIconBadgeNumber, since perhaps some code in your project is instantly setting the badge count to be zero.

@timacdonald
Copy link

timacdonald commented Apr 24, 2018

@Nightsd01 am I right in saying that v2.8.2 was possibly addressing this issue with "The SDK now handles badge count logic on the device itself instead of relying on the backend"

@djendacott
Copy link

djendacott commented Apr 26, 2018

Has anyone had success managing the badge count using v2.8.2?

Our badge count will increment correctly until we open the app and kill it. The badge count will still show correctly until the next push notification, when it will reset back to 1. I assume it must still be getting the count from the server.

Does something specific need to be changed in the OneSignalNotificationServiceExtension to get the device to start handling the badge count?

Alternatively: is it possible to send the request to reset the server count on demand (eg. when the user opens the chat screen) instead of automatically on app open?

@djendacott
Copy link

@Nightsd01 Any update on this?

@damirstuhec
Copy link

This is seriously a huge problem and causes a lot of challenges in managing the badge count. Can we get any updates on this?

@Nightsd01
Copy link
Contributor

To anyone having this problem, client-side badge count logic fixes this issue. However, it only applies to apps created after mid June. It requires adding the Extension Service to your app.

We don't have a switch right now in the dashboard to enable this, so currently you would want to contact OneSignal support and we can enable client side badge logic for your app.

@rgomezp
Copy link
Contributor

rgomezp commented Apr 2, 2019

Closing issue.

@rgomezp rgomezp closed this as completed Apr 2, 2019
@chenkuanhuaian
Copy link

Hi, I'm facing exact the same problem, badge number is not reset at OneSignal.
I have added OneSignal_disable_badge_clearing and OneSignal_app_groups_key
to my info.plists as above had suggested, but still, badge number is not reset.

I wonder what might went wrong...

Also, I don't know if that matters but do I have to name my appGroup following this naming rule : group.{your_bundle_id}.onesignal ?
because I had named my appGroup following other naming rule.

@rgomezp
Copy link
Contributor

rgomezp commented Jun 24, 2019

@chenkuanhuaian ,
Make sure the app group follows that naming rule and try again

@Ankush-Redapple
Copy link

Please follow https://documentation.onesignal.com/docs/ios-sdk-app-groups-setup in detail.

The name of your app group should be group.{your_bundle_id}.onesignal. So for example, if your application's bundle identifier is com.test.app, your app group name should be group.com.test.app.onesignal.

Assign the group to both target.

  1. Open your Info.plist file and add a new OneSignal_app_groups_key as a String type.
  2. Enter the group name you checked in the last step as it's value.
  3. Make sure to do the same for the Info.plist under the OneSignalNotificationServiceExtension folder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests