Closed DevonBernard closed 3 years ago
I have a similar issue. I can't get to the point where the registration occurs, due to issues with the requesting of permissions on the device. I am attempting to implement push notifications on iOS.
After troubleshooting this for hours, there seems to be minute but significant errors in the documentation that I am unable to work through.
After finally identifying that I need to update all @capacitor
packages to @next
errors continued to occur. My TypeScript wouldn't transpile when using PushNotification.requestPermission()
(as shown here) due to requestPermission
not existing in PushNotification
.
It suggested requestPermissions()
which is in the declaration file; however, that function doesn't operate the same as in the above-linked doc. I try to run it anyway with a couple of tweaks that allow TypeScript to transpile. When running on a side-loaded device, I get the following:
[error] - ERROR Error: Uncaught (in promise): TypeError: u.requestPermissions is not a function. (In 'u.requestPermissions()', 'u.requestPermissions' is undefined)
So, apparently neither requestPermission()
or requestPermissions()
exist? I can't even try requestPermission()
because TypeScript won't let me.
I've tried with the @next
, 2.0.2
, 2.0.0
, 1.5.4
, and even 1.4.0
version of the @capacitor
modules core
and ios
with no change in behavior (except unrelated issues re: swizzling in FCM with 1.5.2
and 1.4.0
but that was expected).
I'm not sure how else to try and figure out/work around this?
Naturally, 2 seconds after I post on the issue, I nuked my node_modules
and Xcode Derived Data folder/build cache. I re-targeted 2.0.2
versions and npm install && ng build --prod && npx cap sync && npx cap open ios
and it worked as expected (the requestPermission()
) and also the registration event fired correctly.
@DevonBernard perhaps you should try going to 2.0.2
and cleaning/rebuilding everything? Looks like you're on 2.0.0
which I also had issues with.
Yeah, when I was using 2.0.0 and 2.0.1, I occasionally got a fix similar to the way you did. Sometimes rm -rf node_modules
wasn't sufficient and I had to remove package-lock.json
as well. But doing that and full build ionic build && npx cap sync && npx cap copy
tends to work.
That said, with 2.0.2 I think I've only had this issue once. I won't be surprised if sometime in the next few weeks I'll get the same error again with 2.0.2; I just hope clearing node will be a reliable fix and it's not just coincidence. Would be nice to have a reproducible guide with steps on effectively clearing XCode and Android Studio caches too.
Side note, when versions are aligned and installed correctly, the demo-repo above does work for storage, and push notifications (including APN->FCM conversion for Firebase).
I'm seeing something similar with a starter iOS project. PushNotification.requestPermission() is causing the prompt to display on my iPhone, but my PushNotifications.addListener('registration') callback isn't being called.
The only thing I can think that could be a problem is I have Cocoapods 1.7.5 -- would that cause this problem?
@ryantinker can you post any code? The registration event is not fired when requestPermission()
is called. Registration is actually fired when the device registers with the cloud messaging server.
@rnwolfe Oh interesting. Yes I can totally post code. This is just a starter project and I'm trying to exercise all these cool features. Just a minute.
So, one thing to know about all this: The PushNotifications.addListener('registration') callback is working on Android. I'm getting the token back (and alerting it).
This is only a problem on iOS.
home.page.ts:
ngOnInit() {
// On success, we should be able to receive notifications
PushNotifications.addListener('registration',
(token: PushNotificationToken) => {
alert('Push registration success, token: ' + token.value);
console.log('Success:' + token.value);
}
);
// Some issue with our setup and push will not work
PushNotifications.addListener('registrationError',
(error: any) => {
alert('Error on registration: ' + JSON.stringify(error));
console.log('Error registration');
}
);
// Show us the notification payload if the app is open on our device
PushNotifications.addListener('pushNotificationReceived',
(notification: PushNotification) => {
alert('Push received: ' + JSON.stringify(notification));
}
);
// Method called when tapping on a notification
PushNotifications.addListener('pushNotificationActionPerformed',
(notification: PushNotificationActionPerformed) => {
alert('Push action performed: ' + JSON.stringify(notification));
}
);
}
async requestPushPermission() {
// Request permission to use push notifications
// iOS will prompt user and return if they granted permission or not
// Android will just grant without prompting
PushNotifications.requestPermission().then( result => {
if (result.granted) {
console.log('Request granted!', result);
// Register with Apple / Google to receive push via APNS/FCM
PushNotifications.register();
} else {
// Show some error
console.log('Request failed!');
}
});
}
I've got my GoogleService-Info.plist with the correct BUNDLE_ID.
Over in my AppDelegate.swift:
import Firebase
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
return true
}
...
#if USE_PUSH
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidFailToRegisterForRemoteNotificationsWithError.name()), object: error)
} else if let result = result {
NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidRegisterForRemoteNotificationsWithDeviceToken.name()), object: result.token)
}
}
}
@ryantinker are you getting any console log from the line console.log('Request granted!', result);
? I'm wondering if the if(result.granted)
is executing.
Oh yeah, great question. I meant to actually highlight that line and say: "Yes I'm getting the console.log('Request granted!', result);
line to execute.
Here's a screenshot of my app showing the prompt:
And here's the lines from the xcode log (you can see 'Request granted!'):
⚡️ To Native -> App addListener 39641457
APP INACTIVE
APP ACTIVE
2020-05-15 10:58:11.041203-0700 App[1318:242354] [general] Connection to daemon was invalidated
⚡️ To Native -> PushNotifications requestPermission 39641458
APP INACTIVE
⚡️ TO JS {"granted":true}
⚡️ [log] - Request granted! {"granted":true}
⚡️ To Native -> PushNotifications register 39641459
⚡️ TO JS {}
Some notes:
ionViewDidLoad()
to ngOnInit()
(I was playing with those).That didn't seem to fix anything.
One other note: I can see all the listeners being added in Xcode, but there's a weird "Connection to daemon was invalidated" at the end.
⚡️ To Native -> PushNotifications addListener 97548415
⚡️ To Native -> PushNotifications addListener 97548416
⚡️ To Native -> PushNotifications addListener 97548417
⚡️ To Native -> PushNotifications addListener 97548418
⚡️ To Native -> App addListener 97548419
2020-05-15 11:07:36.172246-0700 App[1359:247447] [general] Connection to daemon was invalidated
The only thing I can think of here is that I have cocoapods 1.7.5 -- from a few years ago. I think I might try installing a Cocoapod manager to bring the latest cocoapods into this project.
I'm also wondering if there's something with my APNS certificate. I have a developer and production one. I bet this app is currently running with my developer certificate, but Firebase only has my production.
Yea, that could be part of it. I actually used Firebase Cloud Messaging entirely for iOS (and haven't messed with Android, yet). I just used whatever XCode did for CocoaPods.
The PushNotifications.register();
should be what results in firing the registration
event. So, it could be that something is going wrong there. Perhaps you can see if there is some sort of catch/console logging you can do on that to see if more info is available.
Okay I think I found the problem. It was something with my APNs certificates/keys.
I believe the certificate being used in my iOS app was not the same certificate that Firebase was using (Firebase uses keys).
I re-created some keys and certificates, reuploaded them all, and it finally works.
Are you still having an issue @ryantinker ?
I also had the problem registering push notification/getting the token, I tried many options discussed on the internet and none seemed to work.
Finally, based on the below text from Apple site (https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/HandlingRemoteNotifications.html) I inserted a valid SIM card with active data plan (there was either none used or not active SIM before because this is my development/test iPhone device) and got the registration token successfully.
If a cellular or Wi-Fi connection is not available, neither the application:didRegisterForRemoteNotificationsWithDeviceToken: method nor the application:didFailToRegisterForRemoteNotificationsWithError: method is called. For Wi-Fi connections, this sometimes occurs when the device cannot connect with APNs over the configured port. If this happens, the user can move to another Wi-Fi network that isn’t blocking the required port. On devices with a cellular radio, the user can also wait until the cellular data service becomes available.
Please also see No Delegate Callbacks section at https://developer.apple.com/library/archive/technotes/tn2265/_index.html
After that I removed SIM card and everything still works even though I'm connected to WiFi only. I'm getting registration token and push notification messages.
It looks like this issue didn't get the information it needed, so I'll close it for now. If I made a mistake, sorry! I am just a bot.
Have a great day! Ionitron 💙
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.
Bug Report
Capacitor Version
npx cap doctor
output: 💊 Capacitor Doctor 💊Latest Dependencies:
@capacitor/cli: 2.0.2
@capacitor/core: 2.0.2
@capacitor/android: 2.0.2
@capacitor/electron: 2.0.2
@capacitor/ios: 2.0.2
Installed Dependencies:
@capacitor/electron not installed
@capacitor/cli 2.0.0
@capacitor/android 2.0.0
@capacitor/ios 2.0.0
@capacitor/core 2.0.0
Affected Platform(s)
Current Behavior
Whenever I re-compile my app
ionic capacitor copy
there is a ~40% chance that all my plugins stop working. The Plugins I'm currently using are [Device, PushNotifications, Storage, SplashScreen, and AdMob].When I say stop working, there are two specific cases in mind:
PushNotifications.register();
, butPushNotifications.addListener('registration')
nor any other listener fire.Storage.set()
and it never even saves the value to memory.I specifically notice this starts getting buggy when I install new npm packages or clear the cache of XCode or Android Studio.
Expected Behavior
After successfully confirming Plugins like PushNotifications and Storage work in iOS/Android... rebuilding the project with
ionic capacitor copy
should not stop Plugins from working.If I clear my cache in XCode or Android Studio, I'd expect running
npx cap sync && cd ios/app && pod install && cd ../../ && ionic capacitor copy
should get everything re-synced and working again.I'd even optionally add:
rm -rf ./node_modules && npm install
before the commands above, but that still seems to be flaky.Sample Code or Sample Application Repo
Reproduction Steps
I made a Github Repo where you can clone an MVP of testing device, storage, and push-notification plugins. The README has all steps to setup and test.
In this demo repo:
Other Technical Details
npm --version
output: 6.11.3node --version
output: v12.11.1pod --version
output (iOS issues only): 1.9.1Other Information