arnesson / cordova-plugin-firebase

Cordova plugin for Google Firebase
http://arnesson.github.io/cordova-plugin-firebase
MIT License
1.01k stars 1.56k forks source link

Problem with iOS notifications #970

Open RicardoMSFaria opened 5 years ago

RicardoMSFaria commented 5 years ago

Describe the bug Notifications does not appear.

Steps to reproduce the behavior:

1. npm i cordova
2. cordova plugin add cordova-plugin-firebase --save
3. cordova platform add ios

Expected behavior Notifications appear when app is closed or background

Implemented code

window.FirebasePlugin.getToken(function(token) {
            console.log('token: ' + token);
        }, function(error) {
            console.error(error);
        });
window.FirebasePlugin.hasPermission(function(data){
                if (!data.isEnabled) {
                    window.FirebasePlugin.grantPermission().then(data => {
                        window.FirebasePlugin.subscribe('ios_test');
                        console.log('permission granted');
                    })
                    .catch(error => {
                        console.error('Error getting permissions', error);
                        return false;
                    });
                } 
                else {
                    console.log('Already has permission');
                    window.FirebasePlugin.subscribe('ios_test');
                }
            });

Console Logs

[3214:2441143]token: eOPj1NEPqb0:APA91bEkVtc2CA...
[3214:2441143]Already has permission
[3214:2441278]5.7.0 - [Firebase/Messaging][I-FCM002024] Format '/topics/ios_test' is deprecated. Only 'ios_test' should be used in subscribeToTopic.

With Notification payload:

(
    [notification] => Array
        (
            [title] => Title test
            [body] => Body test
        )

    [data] => Array
        (
            [title] => Title test
            [text] => Text test
        )

    [priority] => high
    [to] => /topics/ios_test
)

Nothing happens. But with Data only payload:

(
    [data] => Array
        (
            [title] => Title test
            [text] => Text test
        )

    [priority] => high
    [to] => /topics/ios_test
)

In this case, I get the data when the app is in foreground but no notification when the app is closed or in background.

[3231:2468704] Received data message: {
    from = "/topics/ios_test";
    text = "Text test";
    title = "Title test";
}

Plugin Version cordova-plugin-firebase 2.0.5

Smartphone (please complete the following information):

Additional context I know this is possible with this plugin, since I already had this version working. I feel like I'm missing something. Can you help me.

RicardoMSFaria commented 5 years ago

Update: On Android everything is working properly. Works with Notification payload and Data only payload.

Could it be a compatibility issue? Is there any incompatibility with the other plugins I have:

com.telerik.plugins.nativepagetransitions 0.6.5 "Native Page Transitions"
cordova-android-support-gradle-release 2.0.1 "cordova-android-support-gradle-release"
cordova-open-native-settings 1.5.1 "Native settings"
cordova-plugin-add-swift-support 1.7.2 "AddSwiftSupport"
cordova-plugin-android-fingerprint-auth 1.4.4 "FingerprintAuth"
cordova-plugin-badge 0.8.8 "Badge"
cordova-plugin-certificates 0.6.4 "Certificate Plugin"
cordova-plugin-console 1.1.0 "Console"
cordova-plugin-device 2.0.2 "Device"
cordova-plugin-dialogs 2.0.1 "Notification"
cordova-plugin-firebase 2.0.5 "Google Firebase Plugin"
cordova-plugin-health 1.1.0 "Cordova Health"
cordova-plugin-navigationbar 1.0.31 "Cordova NavigationBar plugin"
cordova-plugin-screen-orientation 3.0.1 "Screen Orientation"
cordova-plugin-secure-storage 3.0.0 "SecureStorage"
cordova-plugin-statusbar 2.4.2 "StatusBar"
cordova-plugin-touch-id 3.3.1 "Touch ID"
cordova-plugin-whitelist 1.3.3 "Whitelist"
es6-promise-plugin 4.2.2 "Promise"
florianchevallier commented 5 years ago

Hi, I come accross the same issue. When your app goes into background, do you have the "Disconnected from FCM" log ?

For instance, here are my plugins :

com.adjust.sdk 4.14.0 "Adjust"
cordova-custom-config 5.0.2 "cordova-custom-config"
cordova-plugin-compat 1.2.0 "Compat"
cordova-plugin-firebase 2.0.5 "Google Firebase Plugin"
cordova-plugin-geolocation 2.4.3 "Geolocation"
cordova-plugin-inappbrowser 1.7.2 "InAppBrowser"
cordova-plugin-ionic-keyboard 2.1.3 "cordova-plugin-ionic-keyboard"
cordova-plugin-market 1.2.0 "Market"
cordova-plugin-network-information 2.0.1 "Network Information"
cordova-plugin-passbook 0.2.1 "Passbook"
cordova-plugin-splashscreen 4.1.0 "Splashscreen"
cordova-plugin-statusbar 2.4.2 "StatusBar"
cordova-plugin-whitelist 1.3.3 "Whitelist"
cordova-plugin-x-socialsharing 5.4.3 "SocialSharing"
es6-promise-plugin 4.2.2 "Promise"

Did you try to build your app with the legacy build system ?

Edit: When trying with postman, I have this issue :

{
    "multicast_id": 8653207634570026363,
    "success": 0,
    "failure": 1,
    "canonical_ids": 0,
    "results": [
        {
            "error": "InvalidApnsCredential"
        }
    ]
}
buse974 commented 5 years ago

Hi, Add just window.FirebasePlugin.grantPermission();

it works for me.

florianchevallier commented 5 years ago

Hi, Add just window.FirebasePlugin.grantPermission(); it works for me.

That's what I've already done. The solution was really simple. I didn't set any certificate in firebase (the .p12 file). Well, I'd rather say that the marketing team told me it was all setup, and I shouldn't have believed them.

Case closed for me !

RicardoMSFaria commented 5 years ago

When your app goes into background, do you have the "Disconnected from FCM" log ?

Yes

Hi, Add just window.FirebasePlugin.grantPermission();

it works for me.

I changed to this code. Now I get the error:

5.7.0 - [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented

RicardoMSFaria commented 5 years ago

Did you try to build your app with the legacy build system ?

Yes. I'm using Xcode 9.4.1

buse974 commented 5 years ago

try in Xcode in your -Info.list add or set FirebaseAppDelegateProxyEnabled = true

buse974 commented 5 years ago

or in your config.xml add

<platform name="ios">
<config-file parent="FirebaseAppDelegateProxyEnabled" platform="ios" target="*-Info.plist"><true /></config-file>
</platform>
florianchevallier commented 5 years ago

@RicardoMSFaria : Here is the exact code I have after the ondeviceready event.

window.FirebasePlugin.hasPermission((data) => {
      if (data.isEnabled) {
        console.log("Permission already granted");
      } else {
        window.FirebasePlugin.grantPermission(() => {
          console.log("Permission granted", data.isEnabled);
        }, (error) => {
          console.error("unable to grant permission", error);
        });
      }
    }, error => {
      console.log("hasPermission failed", error);
    });

    window.FirebasePlugin.getToken((token) => {
      console.log(`Firebase Token from cordova: ${token}`);
    }, (error) => {
      console.error("unable to create token", error);
    });

In firebase (here : https://console.firebase.google.com/project/YOUR-PROJECT/settings/cloudmessaging/ ), add the .p12 file

To test easily, you can launch Postman and import this collection :

{
  "id": "f6e6ac05-6b9c-e7e1-7f91-23ca7ca55b5d",
  "name": "Test Firebase",
  "description": "",
  "order": [
    "b95718b2-6464-887a-ffc3-481b46ea180b"
  ],
  "folders": [],
  "folders_order": [],
  "timestamp": 1511419780805,
  "owner": "80140",
  "public": false,
  "requests": [
    {
      "id": "b95718b2-6464-887a-ffc3-481b46ea180b",
      "headers": "Authorization: key=<ENTER_YOUR_LEGECY_KEY - OR - SERVER_KEY>\nContent-Type: application\/json\n",
      "headerData": [
        {
          "key": "Authorization",
          "value": "key=<ENTER_YOUR_LEGECY_KEY - OR - SERVER_KEY>",
          "description": "",
          "enabled": true
        },
        {
          "key": "Content-Type",
          "value": "application\/json",
          "description": "",
          "enabled": true
        }
      ],
      "url": "https:\/\/fcm.googleapis.com\/fcm\/send",
      "queryParams": [],
      "preRequestScript": null,
      "pathVariables": [],
      "pathVariableData": [],
      "method": "POST",
      "data": [],
      "dataMode": "raw",
      "tests": null,
      "currentHelper": "normal",
      "helperAttributes": [],
      "time": 1511614084647,
      "name": "FCM Message POST",
      "description": "Send Direct Message to Device with given id. HTTP Request.",
      "collectionId": "f6e6ac05-6b9c-e7e1-7f91-23ca7ca55b5d",
      "responses": [],
      "rawModeData": "{\n\t\"to\" : \"YOUR TOKEN\",\n\t\"collapse_key\" : \"type_a\",\n\t\"data\" : {\n\t\t\"body\" : \"First Notification\",\n\t\t\"title\": \"ALT App Testing\",\n\t\t\"key_1\" : \"Data for key one\",\n\t\t\"key_2\" : \"Hellowww\"\n\t}\n}"
    }
  ]
}

It's easier to debug

RicardoMSFaria commented 5 years ago

@florianchevallier I try your code and after grant permission on iOS, the result log was:

5.7.0 - [Firebase/Messaging][I-FCM002023] The object <FirebasePlugin: 0x10178af30> does not respond to -messaging:didReceiveRegistrationToken:. Please implement messaging:didReceiveRegistrationToken: to be provided with an FCM token.

Permission granted false

Launched Postman with your collection and it post without errors

status →200

But, again the log on xcode was:

5.7.0 - [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented

I'll try @buse974 solution.

chrum commented 5 years ago

Hello, I am fighting with this thing for last, dunno, 48hours and still nothing stable :( along the way i was able to receive notifications occasionally but when trying to repeat with fresh app... weirdness

anyway, additionally to this xcode output presented above i had to deal with provisioning (dev builds) and commenting out line 56 (embedded.mobileprovision is removed there…) in file: node_modules/cordova-ios/bin/templates/scripts/cordova/lib/copy-www-build-step.js which helped with xcode complaints

also notifications started to show up (ocassionally) with app closed when i added this to config.xml

<platform name="ios">
  <config-file target="*-Info.plist" parent="UIBackgroundModes">
      <array>
        <string>remote-notification</string>
      </array>
    </config-file>
</platform>

(yes, this can be done from xcode but we are config.xml centered here ;) )

its super weird because push notifications integration is dead easy (i have non technical clients who manage to do that themselves) so i wonder if its the lib or we are missing the final piece?

as a side note, onesignal simply works. I just did the minimal configuration and boom i have what i expected in less than 30minutes

charlie-rushton commented 5 years ago

After a week or so of internet trawling, I managed to get my notifications on iOS working.

I initially followed the medium guide (https://medium.com/@felipepucinelli/how-to-add-push-notifications-in-your-cordova-application-using-firebase-69fac067e821) to try and get the notifications working. This didn't work. However, I still followed the steps in the guide, and then made the following changes.

Firstly I changed the build system to Legacy in File -> Project Settings.

Secondly, I used an Authentication APN Key (not Certificate as mentioned in the Medium guide, see https://firebase.google.com/docs/cloud-messaging/ios/certs).

I then noticed in XCode that the Cordova folder and Info.plist inside that folder were highlighted in red, on further investigation I noticed that this folder and file did not exist in the specified location. I searched in the folder 'cordovaApp' using Finder and located the Info.plist file, it was showing the file was last modified in 1985 (weird). I created the Cordova folder and moved Info.plist into this folder, and in XCode I clicked on the missing Cordova folder and changed the location to Absolute Path (see below screenshots), the folder and file now appeared white. N.B. I have no idea if this made a difference or not, just thought I should include it as it was one of the steps I took.

screenshot 2018-12-21 at 13 00 11 screenshot 2018-12-21 at 13 01 23

Next, I added the following XML (shoutout @chrum ) to my config.xml and also made the added changes in -Info.plist.

<platform name="ios">
  <config-file target="*-Info.plist" parent="UIBackgroundModes">
      <array>
        <string>remote-notification</string>
      </array>
    </config-file>
</platform>

Note: with the UIBackgroundModes XML change, you have to manually add this change. In -Info.plist, add a new row. In the 'Key' Column, type 'UIBackgroundModes', set the Type to be 'Array'. Expand out the newly created row and add 'remote-notification' in the value column. Also note that these two rows are renamed automatically in XCode 10. I also had to manually change the value of FirebaseAppDelegateProxyEnabled in -Info.plist from 'YES' to 'NO'.

After making these changes, I manually uninstalled the app from my iOS device, and then built and installed the app back onto my device, and then the notifications from Firebase began to appear.

EDIT The only client side code I used was @florianchevallier code posted above in the deviceReady section of my index.js file:

window.FirebasePlugin.hasPermission((data) => {
      if (data.isEnabled) {
        console.log("Permission already granted");
      } else {
        window.FirebasePlugin.grantPermission(() => {
          console.log("Permission granted", data.isEnabled);
        }, (error) => {
          console.error("unable to grant permission", error);
        });
      }
    }, error => {
      console.log("hasPermission failed", error);
    });

    window.FirebasePlugin.getToken((token) => {
      console.log(`Firebase Token from cordova: ${token}`);
    }, (error) => {
      console.error("unable to create token", error);
    });
mesqueeb commented 5 years ago

@charlie-rushton for the past two days i've spent 16+ hours trying to get this to work. these three steps worked for me:

Didn't do anything else of your guide but this still fixed it for me. Thanks so much.

peterpeterparker commented 5 years ago

I just gonna let that msg here in case that would help you or someone else in the future, as I was facing a while the error didReceiveRegistrationToken too

  1. AS @mesqueeb correctly pointed out, in Xcode, remote notifications should be activated respectively the following key should be add to the Info.plist
<key>UIBackgroundModes</key>
    <array>
        <string>remote-notification</string>
    </array>
  1. It may sound silly but that's the main reason why it didn't work for me, in a Cordova app, wait till the platform is ready (platform.ready) before trying to get the token. If the platform ain't ready, the error didReceiveRegistrationToken will be displayed
bryyyanribo commented 5 years ago

Hi Guys, I'm still having issues on this one. I can receive the notification on Background but I can't display it on the foreground it doesn't show up. I even added a console.log, toast and alert just to display it out but it doesn't show or log the data I receive on XCode.

It's working on Android but I have to make it work on iOS. Any luck?

evinkuraga commented 5 years ago

@bryyyanribo Did you ever end up fixing this?

To everyone else, I've followed everyone's steps in this thread including a few other threads. Have spent 3 days now trying to get this to work. I'm pretty deflated at this point... So I'm offering a monetary reward to anyone who will either provide me with the fix. I can't for the life of me figure out where the problem is happening..

Here are a few questions:

  1. Can we experiment this on a virtual device, or does it have to be on a physical device?
  2. If I see the payload appear in xcode console, does this mean that the config was done properly and that the issue is within the internal configs?
  3. When I close the app, xcode console log's shows "Disconnected from FCM". Is this normal behaviour?
  4. After closing the app and seeing "Disconnected from FCM", when sending a message to a device no longer logs anything. Is this normal behaviour? Obviously nothing appears in the notification drawer either.

Any ideas? What could I possibly missing? Other solutions I have attempted: installing ios 5.0.0 and switching back from legacy to modern. Alternating between a p8 authentication to p12 certificates Creating a fresh cordova project, just install firebase, doing the fcm configs listed above and tryign the same steps.. (still not getting anything).

bryyyanribo commented 5 years ago

Hey @evinkuraga, yes I fixed this issue. Do you have a slack or email so I could send to you all of the stuffs I did? And If it did work, I'll add it here on this thread to share it to others 😁

evinkuraga commented 5 years ago

@bryyyanribo skype: evinkuraga email: (a temporary image to be removed later)

minimedj commented 5 years ago

@bryyyanribo Hi, I have exactly the same issue and ready to help testing. Please share!

skype: max.bourinov

BinaryBlock commented 5 years ago

@bryyyanribo Any chance you can post the solution?

minimedj commented 5 years ago

@BinaryBlock I will post my findings in next few days. Looking forward to get hards on iOS push notifications issue.

BinaryBlock commented 5 years ago

@BinaryBlock I will post my findings in next few days. Looking forward to get hards on iOS push notifications issue.

SUPER-THANKS! Would be greatly appreciated.

rodriguezmanu commented 5 years ago

please share, thanks

remisture commented 5 years ago

How to get around the "5.7.0 - [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented" errors on iOS?

dmarg commented 5 years ago

I've done all the steps from the above link https://github.com/arnesson/cordova-plugin-firebase/issues/970#issuecomment-449385556 and am still not getting notifications in the background. Any other suggestions? Anybody else still having these issues?

bryyyanribo commented 5 years ago

Hi, guys! Here are my suggestions for you to make it work:

"cordova-plugin-firebase": "^2.0.5",

ionic cordova platform rm ios
ionic cordova platform add ios@5.0.0
ionic cordova prepare ios 

Some notes:

Then open the app on Xcode by opening the platforms/ios and then open the project (not the Xcode Project but the dev space something). Then run the project.

I set my deployment target to ios 10. Also, make sure you have set up the Certificates and App ID on your Apple Developer account

App ID: Make sure you're enabling the Push Notifications on both Development and Distribution Provisioning Profiles: Make sure you set up those ones and add the appropriate certificates and devices if your testing it out physically.

Certificates: Apple Push Services and APNS Development iOS

Some of the answers, I found them on GitHub and other sources but I can't remember the links. If anyone could add them out please do comment the links :D

minimedj commented 5 years ago

@BinaryBlock As I promised earlier here is how I have solved it: I stoped using Firebase for iOS, instead I send directly via APNs.

BinaryBlock commented 5 years ago

@minimedj :joy: Thanks for the update.

So... I did like a dozen things since I posted here... and got mine working. I believe the biggest thing for me that got the push notifications (alerts) to appear on iOS with my Ionic v3 app in the background... had nothing to do with the Ionic app itself.

We are using a Java web service to submit the push notifications to Firebase... to then send out to iOS and Android. I was only sending the push notifications in the Android format in Java and not the iOS format that was needed. The documentation was really lacking on the whole Firebase thing, in my humble opinion.

The snippet of Java code for formatting the push for either Android or iOS is as follows (in case that helps someone/anyone):

        Message message = Message.builder()
                .setApnsConfig(
                        ApnsConfig.builder()
                                .putHeader("apns-priority", "10")
                                .setAps(Aps.builder()
                                        .setAlert(ApsAlert.builder()
                                                .setTitle(title)
                                                .setBody(body)
                                                .build())
                                        .build())
                                .build()
                )
                .setAndroidConfig(AndroidConfig.builder()
                        .setTtl(ttl) // 1 hour in milliseconds
                        .setPriority(priority)
                        .setNotification(builder.build())
                        .build())
                .setToken(regId)
                .build();

        String response = FirebaseMessaging.getInstance().send(message, dryRun);

Thanks for keeping your word and writing your solution. :+1:

Sampath-Lokuge commented 5 years ago

Ionic 4:

My problem was I didn't use the legacy build system when I deployed the app to the device. After using the Lagacy build system it works.

ash737 commented 2 years ago

@RicardoMSFaria : Here is the exact code I have after the ondeviceready event.

window.FirebasePlugin.hasPermission((data) => {
      if (data.isEnabled) {
        console.log("Permission already granted");
      } else {
        window.FirebasePlugin.grantPermission(() => {
          console.log("Permission granted", data.isEnabled);
        }, (error) => {
          console.error("unable to grant permission", error);
        });
      }
    }, error => {
      console.log("hasPermission failed", error);
    });

    window.FirebasePlugin.getToken((token) => {
      console.log(`Firebase Token from cordova: ${token}`);
    }, (error) => {
      console.error("unable to create token", error);
    });

In firebase (here : https://console.firebase.google.com/project/YOUR-PROJECT/settings/cloudmessaging/ ), add the .p12 file

To test easily, you can launch Postman and import this collection :

{
  "id": "f6e6ac05-6b9c-e7e1-7f91-23ca7ca55b5d",
  "name": "Test Firebase",
  "description": "",
  "order": [
    "b95718b2-6464-887a-ffc3-481b46ea180b"
  ],
  "folders": [],
  "folders_order": [],
  "timestamp": 1511419780805,
  "owner": "80140",
  "public": false,
  "requests": [
    {
      "id": "b95718b2-6464-887a-ffc3-481b46ea180b",
      "headers": "Authorization: key=<ENTER_YOUR_LEGECY_KEY - OR - SERVER_KEY>\nContent-Type: application\/json\n",
      "headerData": [
        {
          "key": "Authorization",
          "value": "key=<ENTER_YOUR_LEGECY_KEY - OR - SERVER_KEY>",
          "description": "",
          "enabled": true
        },
        {
          "key": "Content-Type",
          "value": "application\/json",
          "description": "",
          "enabled": true
        }
      ],
      "url": "https:\/\/fcm.googleapis.com\/fcm\/send",
      "queryParams": [],
      "preRequestScript": null,
      "pathVariables": [],
      "pathVariableData": [],
      "method": "POST",
      "data": [],
      "dataMode": "raw",
      "tests": null,
      "currentHelper": "normal",
      "helperAttributes": [],
      "time": 1511614084647,
      "name": "FCM Message POST",
      "description": "Send Direct Message to Device with given id. HTTP Request.",
      "collectionId": "f6e6ac05-6b9c-e7e1-7f91-23ca7ca55b5d",
      "responses": [],
      "rawModeData": "{\n\t\"to\" : \"YOUR TOKEN\",\n\t\"collapse_key\" : \"type_a\",\n\t\"data\" : {\n\t\t\"body\" : \"First Notification\",\n\t\t\"title\": \"ALT App Testing\",\n\t\t\"key_1\" : \"Data for key one\",\n\t\t\"key_2\" : \"Hellowww\"\n\t}\n}"
    }
  ]
}

It's easier to debug

Hi @florianchevallier , I'm very new in ionic. I have the same problem ios notification not work. May I know where I add this code please?

florianchevallier commented 2 years ago

I have to admit that it was like 3 years ago and I don't remember at all ^^