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

Action Buttons not appearing on iOS until notification made explicitly rich by adding picture #430

Closed
XenorPLxx opened this issue Oct 4, 2018 · 35 comments · Fixed by #597

Comments

@XenorPLxx
Copy link

XenorPLxx commented Oct 4, 2018

Description:

Hello!

I've setup OneSignal push notifications in my React Native app that is build for both Android and iOS.

I'm trying to send basic notification from OneSignal dashboard that includes buttons. While my app is in foreground, everything looks fine - I see buttons in payload, so I display them in in-app notification.

When application is in background or closed, buttons are handled as a part of system notification. On Android it works fine, but on iOS I don't see the buttons (even tho they are in payload in my opened eventListener.

I rechecked if native setup done correctly on iOS and I've started to play with different settings in the OneSignal dashboard. After I've added picture to iOS notification (with buttons setup), I've got BOTH picture and buttons. And after that, even without picture, I've started getting buttons correctly on iOS.

It all worked until I've tried removing app from my phone. After reinstallation buttons disappeared and again, sending picture once made them available in later notifications.

React Native library is just a SDK wrapper for handling notifications, hence I think this is the best place to put that issue in.

Environment

  1. What version of the iOS SDK are you using?
    react-native 3.2.7 includes iOS SDK 2.8.8 (per https://github.com/geektimecoil/react-native-onesignal/releases)
  2. How did you add the SDK to your project (eg. cocoapods)
    Linking
  3. iOS version
    12.0, 12.1

Steps to Reproduce Issue:

  1. Setup notifications
  2. Try sending buttons with notification
  3. Observe, if buttons are available in system notification (app in background)
  4. If not, try adding picture to make notification Rich
  5. Again observe, if buttons are available in system notification (app in background)
@Nightsd01
Copy link
Contributor

Nightsd01 commented Oct 4, 2018

@XenorPLxx Can you share how you set up your Notification Service Extension?

Also, in iOS, buttons will not show up at all unless you force-press on the notification. This is not a bug. It is iOS system behavior. You need to force-press/pull down to see the buttons. Just want to make sure that's not the issue.

@XenorPLxx
Copy link
Author

XenorPLxx commented Oct 4, 2018

Hiya.

Thanks for the response. I'm aware that I have to use 3D touch to make buttons appear on iOS, that is not the case. Buttons do not appear until I send at least one notification with picture included.

For setup I've followed https://documentation.onesignal.com/v5.0/docs/react-native-sdk-setup, including adding Notification Service Extension with Objective-C code.

For sending notifications I've tried both OneSignal dashboard (although buttons are part of Android notification there) and API by following documentation, which states that buttons work for both Android and iOS.

I can upload screens of the steps mentioned in setup documentation tomorrow when I'll have access to my workstation if needed.

I know that my colleague was able to reproduce the issue on some other project, I'm not sure if solution with sending picture worked for him though. I'll check with him tomorrow.

@Nightsd01
Copy link
Contributor

Can you send your NotificationService.m and NotificationService.h files?

Can you also post a screenshot of the Xcode Project Settings for your OneSignalNotificationServiceExtension target, especially the Link Binary with Libraries section, and can you also post your Podfile?

@XenorPLxx
Copy link
Author

XenorPLxx commented Oct 4, 2018

NotificationService.h:

//
//  NotificationService.h
//  OneSignalNotificationServiceExtension
//
//  Created by *** on 29/05/2018.
//  Copyright © 2018 Facebook. All rights reserved.
//

#import <UserNotifications/UserNotifications.h>

@interface NotificationService : UNNotificationServiceExtension

@end

NotificationService.m:

#import <RCTOneSignalExtensionService.h>

#import "NotificationService.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNNotificationRequest *receivedRequest;
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
  self.receivedRequest = request;
  self.contentHandler = contentHandler;
  self.bestAttemptContent = [request.content mutableCopy];
  
  [RCTOneSignalExtensionService didReceiveNotificationRequest:self.receivedRequest withContent:self.bestAttemptContent];
  
  // DEBUGGING: Uncomment the 2 lines below and comment out the one above to ensure this extension is excuting
  //            Note, this extension only runs when mutable-content is set
  //            Setting an attachment or action buttons automatically adds this
  // NSLog(@"Running NotificationServiceExtension");
  // self.bestAttemptContent.body = [@"[Modified] " stringByAppendingString:self.bestAttemptContent.body];
  
  self.contentHandler(self.bestAttemptContent);
}

- (void)serviceExtensionTimeWillExpire {
  // Called just before the extension will be terminated by the system.
  // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
  
  [RCTOneSignalExtensionService serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
  
  self.contentHandler(self.bestAttemptContent);
}

@end

app target capabilities:
screenshot 2018-10-04 at 22 15 48
screenshot 2018-10-04 at 22 22 33

OneSignalNotificationServiceExtension header search paths:
screenshot 2018-10-04 at 22 17 57

OneSignalNotificationServiceExtension target Link Binary with Libraries:
screenshot 2018-10-04 at 22 15 18

Podfile (there's almost nothing there, as we use dependencies from npm packages):

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
workspace 'myproject.xcworkspace'

target 'myproject' do
  pod 'AppCenter/Crashes', '~> 1.9.0'
  pod 'AppCenter/Analytics', '~> 1.9.0'
  pod 'AppCenterReactNativeShared', '~> 1.8.1'
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  use_frameworks!

  pod 'Fabric'
  pod 'Crashlytics'
  
  # Pods for myproject

  platform :ios, '9.0'
  #target 'myproject-tvOSTests' do
    #inherit! :search_paths
    # Pods for testing
  #end

  target 'myprojectTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

target 'myproject-tvOS' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!

  # Pods for myproject-tvOS

  target 'myproject-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

@Nightsd01
Copy link
Contributor

Can you reproduce this behavior in our example project location in /examples/RNOneSignal folder from the react-native repo?

If so, can you please zip up the project and email a dropbox/etc. link to brad@onesignal.com so I can try to reproduce this issue? You don't have to send us your full app - just the demo app after you install dependencies and reproduce the issue.

It would also be helpful for you to give me a Notification ID for one of the notifications that exhibited the problem - even if it's an exact duplicate of a notification that works later on.

It's a bizarre issue - we've never heard of anything like this being reported before - so I'd definitely like to see exactly how you've got things configured.

@XenorPLxx
Copy link
Author

XenorPLxx commented Oct 4, 2018

Sure, I'll prepare reproduction app over the weekend and I'll get back to you.

@XenorPLxx
Copy link
Author

Hello!

I'm happy to inform that I have the repro ready and issue still appears (well, maybe not 'happy' happy, but you know what I mean :D).

After downloading example app I:

  1. Installed dependencies using yarn
  2. Ran third-party glog configurations and relinked libfishhook.a (fix for react-native 0.55.4 Xcode 10 bug)
  3. Changed bundle id and setup automatic signing to use my dev account
  4. Setup new push cert (following https://documentation.onesignal.com/docs/generate-an-ios-push-certificate)
  5. Setup Notification Service Extension (following https://documentation.onesignal.com/v5.0/docs/react-native-sdk-setup)
  6. Setup new app in OneSignal (including iOS cert setup) and changed id in OneSignal.init to my new OneSignal app id
  7. Setup message template that includes button
  8. Built and installed app through Xcode 10 Beta 2 on iPhone X running iOS 12.1 Beta 2 (my colleague tried also stable iOS 12 on iPhone X with the original app)
  9. Registered email in example app and checked, if user is visible in OneSignal dashboard
  10. Sent notificaton with buttons while app in background - no buttons (screen below)
    img_0474
  11. Sent notification with buttons AND iOS picture - buttons appeared (screen below)
    img_0475
  12. Sent notificaton with buttons while app in background - buttons appeared (screen below)
    img_0476
  13. Removed and installed application again
  14. Sent notificaton with buttons while app in background - no button (screen below)
    img_0477

Ziped repro app: https://synology.dawidkarczewski.pl/sharing/AerCCMgV8 (URL will expire at 31.12.2018)

@Nightsd01
Copy link
Contributor

Hey @XenorPLxx thanks for all the details!

I looked into the issue and it looks like your project has the Deployment Target for the OneSignalNotificationServiceExtension set to 12.1.

You will definitely want to change this to 10.0 and that fixes the issue.

I will need to do some further investigation to figure out why building the extension for 12.0+ appears to crash the extension before it can attach buttons/etc. But it works perfectly well with 10.0.

fix

@XenorPLxx
Copy link
Author

XenorPLxx commented Oct 8, 2018

Hiya!

Thanks for the response.
Sadly, it didn't do the trick for me. I've tried both repro app and original app we had problems with and both don't display buttons after removing app from phone and rebuilding with Deployment Target = 10.0 for Notification Extension.

Here's example notification that didn't show buttons:
img_68d0138b2b0b-1

@Nightsd01
Copy link
Contributor

Hi @XenorPLxx I was able to reproduce the issue...until I lowered the deployment target. Now I cannot reproduce, even uninstalling + reinstalling the example app you sent.

I am thinking this may be an issue in the Xcode + iOS betas as these distributions often have bugs. Can you try downgrading to the public releases of Xcode 10 & iOS 12.0 and lower the deployment target of the extension service and tell me if the issue still occurs?

@Nightsd01
Copy link
Contributor

Also, here is an easier way to debug this. Instead of attaching buttons, try replacing the contents of your NotificationService.m with this instead:

#import <RCTOneSignalExtensionService.h>

#import "NotificationService.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNNotificationRequest *receivedRequest;
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
  self.receivedRequest = request;
  self.contentHandler = contentHandler;
  self.bestAttemptContent = [request.content mutableCopy];
  
  self.bestAttemptContent.body = [@"[Modified] " stringByAppendingString:self.bestAttemptContent.body];
  
  self.contentHandler(self.bestAttemptContent);
}

- (void)serviceExtensionTimeWillExpire {
  // Called just before the extension will be terminated by the system.
  // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
  
  [RCTOneSignalExtensionService serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
  
  self.contentHandler(self.bestAttemptContent);
}

@end

Now, when you do that, whenever you receive a rich push notification (with buttons/photos/etc.) the body of the push notification will have [Modified] added to the front of the message. Keep in mind that iOS only knows a push notification is a rich notification if mutable-content is set to true

@XenorPLxx
Copy link
Author

XenorPLxx commented Oct 8, 2018

I'm not really keen on resetting my iPhone to downgrade iOS, so I'll try some device when I'm at work tomorrow that has stable iOS 12 or lower.

I've tried second solution you've provided (with target lowered to 10.0) and as you can see the [Modified] text is there:

img_0479

img_0480

@Nightsd01
Copy link
Contributor

@XenorPLxx Keep in mind that code I posted for NotificationService.m would definitely stop buttons from working even if they had been working in the first place.

I am pretty certain this is a bug in Xcode 10 beta or iOS 12.1 beta. I will attempt to reproduce.

@XenorPLxx
Copy link
Author

XenorPLxx commented Oct 8, 2018

The only test I could do without access to additional iOS devices was to copy over support files for iOS 12.1 to public release XCode 10 and build from there, but it didn't do any change.

I've also tried uncommenting 2 lines in original NotificationService.m (25 & 26) per in-file comment suggestion and I've got [Modified] text, but buttons didn't appear.

@Nightsd01
Copy link
Contributor

Yeah, even with iOS 12 beta + Xcode 10 beta, I cannot reproduce your issue.

Just to make absolutely sure you are setting the deployment target correctly for the extension target and not the app target can you zip up the demo project as you currently have it and send it to me?

@XenorPLxx
Copy link
Author

XenorPLxx commented Oct 8, 2018

Changing target for app is blocked in my Xcode for some reason, I can change only for extension target.

Here's the current app zipped: https://synology.dawidkarczewski.pl/sharing/yHH9UbSQd (URL will expire at 31.12.2018)

@Nightsd01
Copy link
Contributor

I've had another idea. Try this. Try replacing the contents of your NotificationService.m with this.

Then, send a notification with buttons. We want to know two things: (A) Do the buttons appear? And (B) Does the title of the notification show up as [Modified 1] or [Modified 2], or neither?

#import <RCTOneSignalExtensionService.h>

#import "NotificationService.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNNotificationRequest *receivedRequest;
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
  self.receivedRequest = request;
  self.contentHandler = contentHandler;
  self.bestAttemptContent = [request.content mutableCopy];
  
  self.bestAttemptContent.body = [@"[Modified 1] " stringByAppendingString:self.bestAttemptContent.body];
  
  [RCTOneSignalExtensionService didReceiveNotificationRequest:self.receivedRequest withContent:self.bestAttemptContent];
  
   self.bestAttemptContent.body = [@"[Modified 2] " stringByAppendingString:self.bestAttemptContent.body];
  
  self.contentHandler(self.bestAttemptContent);
}

- (void)serviceExtensionTimeWillExpire {
  // Called just before the extension will be terminated by the system.
  // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
  
  [RCTOneSignalExtensionService serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
  
  self.contentHandler(self.bestAttemptContent);
}

@end

@XenorPLxx
Copy link
Author

Here are the result, both text are there, no buttons:

Fresh install:
img_0481
img_0482

Picture attached:
img_0483
img_0484

@XenorPLxx
Copy link
Author

XenorPLxx commented Oct 8, 2018

I've just remembered that earlier today I've changed extension target in the original app that has the same problem and just now I've tested dev release version - it also doesn't show buttons.

Thanks to that I think we can exclude Xcode beta problems - to build mentioned version we use Bitrise and their 'previous stable' Xcode 9.4.1 stack.

I'll test that build with some stable iOS 12 or earlier first thing tomorrow.

@Nightsd01
Copy link
Contributor

I have done some more testing and I have been able to reliably reproduce this issue in iOS 12, both the public release and the beta.

I've done some debugging and I've also been able to verify that our SDK is doing exactly what it should be doing. It's correctly registering a UNNotificationCategory, registering it with the current UNUserNotificationCenter and registering your buttons for that category, and it is also setting the categoryIdentifier on the UNNotificationContent

This is everything the system needs to add the button to the notification, but it still doesn't get added.

I will be reporting this as a bug with iOS, and will be adding the radar issue # here.

@Nightsd01
Copy link
Contributor

In fact this isn't just occurring with React-Native, it's occurring with our normal iOS SDK release as well. Thanks for reporting this and good catch!

@XenorPLxx
Copy link
Author

Always glad to help ^^
Thanks for your time so far. I hope that resolving this issue over on Apple side will be supported so well as it is here in OneSignal :).

@stevesweets
Copy link

Have experienced this issue as well with a react-native build; Finding this report was helpful as i've been able to resolve it with adding an attachment.

@Nightsd01
Copy link
Contributor

I have done further debugging - this is definitely an iOS 12 bug. I've opened a bug report with Apple, here is a radar to track it:

http://openradar.appspot.com/radar?id=5058705502502912

@neo125874
Copy link

@Nightsd01 hi, any further update or workaround could resolve this issue? thanks.

@Nightsd01
Copy link
Contributor

Nightsd01 commented Dec 5, 2018

@neo125874 apparently this issue has been reported before I created my bug report, Apple told me they’re aware of the issue and are working on it. I don’t have an ETA at the moment.

It is quite an aggravating bug. I was able to reproduce even without our SDK. I will update this issue when I hear anything further.

The only workaround I know of is a really annoying one: use the ios_category field and hard-code the button categories with your app by registering UNNotificationCategory (using native code or a react native wrapper framework of some kind)

@User2004
Copy link

https://webappcodes.com/tag/notification

Here is a link for integrate push notification in ios

@mcontin
Copy link

mcontin commented Apr 19, 2019

Any info if this bug has been solved or if it still affects newer releases of iOS 12?

@rgomezp
Copy link
Contributor

rgomezp commented May 29, 2019

I haven't heard any recent complaints about this issue. I think it is safe to close. I will leave it open for another week to see if anyone reports anything @mcontin

@XenorPLxx
Copy link
Author

@GaborWnuk you might want to recheck if issue is still valid ⬆️

@rgomezp
Copy link
Contributor

rgomezp commented Jun 7, 2019

Closing due to no response

@7freaks-otte
Copy link

Anyone still experiencing this except me?

I updated everything to the newest versions (Xcode 11, iOS 13.1.2), have reimplemented OneSignal with Groups and ServiceExtension (target 10.0) several times, even recreated my app from scratch, double/triple/milliontimes checked every step in the documentation, I just don't get the action buttons to work on iOS.

Action buttons work perfectly on Android, they even work on iOS if I attach a picture, but as soon as I remove the picture again, the buttons are gone as well..

@rgomezp rgomezp reopened this Oct 8, 2019
jkasten2 added a commit that referenced this issue Jan 14, 2020
* Re-listing notifications categories after registering to force a refresh of them.
   - See comment for more details.
* These are the dynamic per notification buttons set via the dashboard or REST API
* Issue started to show up in iOS 12
* Fixes #430
jkasten2 added a commit that referenced this issue Jan 14, 2020
* Re-listing notifications categories after registering to force a refresh of them.
   - See comment for more details.
* These are the dynamic per notification buttons set via the dashboard or REST API
* Issue started to show up in iOS 12
* Fixes #430
@Bathant
Copy link

Bathant commented Nov 11, 2020

Is there any updates for this issue? Is it fixed?

@rgomezp
Copy link
Contributor

rgomezp commented Nov 11, 2020

@Bathant ,
Howdy.

I believe this was fixed by #597

You may be experiencing the issue reported in #740

@scrummitch
Copy link

scrummitch commented Nov 28, 2022

If anyone finds this, i still have this issue in another product in 2022, iOS 16.

I firstly solved this by adding a sleep(1) function after i added my category, then listing categories again. Which makes me think there is some disk or synchronisation step in the background happening in the OS.

See below for my better solution, no sleep needed!

 func setCategories(newCategory: UNNotificationCategory) async -> Bool {
        return await withCheckedContinuation {continuation in
            UNUserNotificationCenter.current().getNotificationCategories { categories in
                var allCategories: Set<UNNotificationCategory> = categories
                allCategories.insert(newCategory)
            
                UNUserNotificationCenter.current().setNotificationCategories(allCategories)
                
                UNUserNotificationCenter.current().getNotificationCategories { categories in
                    continuation.resume(returning: true)
                }
            }
        }
    }

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

Successfully merging a pull request may close this issue.