EddyVerbruggen / nativescript-plugin-firebase

:fire: NativeScript plugin for Firebase
https://firebase.google.com
MIT License
1.01k stars 448 forks source link

iOS new AppTrackingTransparency framework #1799

Open karlix opened 3 years ago

karlix commented 3 years ago

Recently admob started displaying this message on the admin page:

"Prepare your applications for iOS 14 Apple has announced the new AppTrackingTransparency framework, by which you must make changes to your iOS applications. Implement version 7.64.0 (or later) of the Google Mobile Ads SDK and create messages from request for consent not to lose a significant part of your advertising revenue. "

https://developer.apple.com/documentation/apptrackingtransparency

Is it possible to implement this with this plugin?

Thank you!

StefanNedelchev commented 3 years ago

There is a plugin that implements the tracking transparency API for NativeScript https://market.nativescript.org/plugins/@nstudio/nativescript-tracking-transparency/ (it's relatively new). However, this plugin only provides the stuff necessary to detect or ask for permission, besides that it's still up to you to enable/disable Firebase features I guess. And for me personally is still a bit unclear if I can use Firebase analytics when the user declines the tracking consent.

StefanNedelchev commented 3 years ago

According to the official iOS 14 support docs it seems to me that we could leave analytics enabled and the regular event logging won't be affected (only features that require IDFA will not work). But it's still unclear if we will need to upgrade to the latest version of the Firebase SDK.

lambourn commented 3 years ago

I just found this in the Firebase documentation.

If we enable Analytics (like "analytics": true, in firebase.nativescript.json) then the plugin's Podfile uses

# Analytics
pod 'Firebase/Analytics'

to get rid of IDFA it might be better to follow Google's approach and use

# Analytics without IDFA
pod 'Firebase/AnalyticsWithoutAdIdSupport'

in the case that no ads are used at all.

lostation commented 2 years ago

Hi All,

I need help to understand... It seems something is broken again, since IOS 14...

One of my client reported that quite suddenly our NS6 app, that is still using firebase plugin v10.5.2, doesn't get any new push notifications IOS side...Android is always working perfectly.

I've checked with my iPhone and indeed that's not working anymore for any reason...sh** : (

I've published my last App Store version on this last June 2021 and push notifications were perfectly working for some weeks on IOS and android...

Now it seems that IOS is blocking the push notification ? Possible ?

If someone has some info about firebase and iOS 14 (18A373) ? What to do with the plugin if any ?

My generated podfile contains only all related push firebase plugin lines...

platform :ios, '9.0' pod 'Firebase/Core', '~>6.16.0' pod 'Firebase/Messaging'

As I understood -> AppTrackingTransparency is used for ads and more precise user targeting process... Normally I shouldn't handle the AppTrackingTransparency if I don't use any analytics stuffs...

I'm only get the device id and store it to link with user token...nothing special...

It's completely unclear of what to do if I need to do anything... -> https://firebase.google.com/docs/ios/supporting-ios-14

Thanks for help if any... Lo.

lostation commented 2 years ago

Ok so it seems I need to use the lib "nativescript-tracking-transparency" cause firebase analytics is used even if it's not intended for... If someone could tell me how to deactivate analytics... ???

So using this... Make the push great again : )

https://github.com/nstudio/nativescript-plugins/tree/master/packages/nativescript-tracking-transparency

with ` // Get App-tracking-transparency Status const status = TrackingTransparency.getTrackingStatus();

        if (status === TrackingStatus.Authorized || status === TrackingStatus.Unavailable)
        {
            // Android or IOS prior to v14
            firebase.init();
        }
        else // Should request access for IOS v14+
        {
            TrackingTransparency.requestTrackingPermission().then(status =>
            {
                switch (status)
                {
                    case TrackingStatus.Authorized:
                        setTimeout(() => firebase.init(), 250);
                        break;
                }
            });
        }

`

Thanks apple...

lambourn commented 2 years ago

@lostation thanks a lot. This should be added to the README for sure.

As for disabling Analytics by default and make it opt-in you need to do the disable it in the Info.plist

<key>FIREBASE_ANALYTICS_COLLECTION_ENABLED</key>
<false/>

Once you know that the user wants to be tracked (taking the above from TrackingTransparency into account), you can enable it via

import { analytics } from "@nativescript/firebase/analytics";
...
enableAnalytics(value: boolean) {
  analytics.setAnalyticsCollectionEnabled(value);
}

see https://firebase.google.com/docs/analytics/configure-data-collection?platform=ios for more information.

lambourn commented 2 years ago

@lostation out of interest, do you use Firebase Messaging for push notifications on iOS and Android or you using the "external push" mechanism so that Firebase just handles the APN messages?

Also, if you do not use any Analytics features at all in your app you could try to disable/opt-out Analytics completely (check your firebase.nativescript.json file in the project, does it have "analytics": true,- if not set it to false, then clean & rebuild). Not sure if that really turns off analytics, you still may need the mentiond Info.plist entry.

lostation commented 2 years ago

Thanks @lambourn

I'm using this plugin to receive regular push notification on IOS and Android through normal firebase workflow. It's still a bit unclear to me what's going on with APN and external push. (external_push_client_only) Our .NET API is simply sending json message title body to Firebase api then the magic will happen... Notification should popup from mobile device ; )

From firebase.nativescript.json file, I only use "messaging: true" (and using_ios, using_android...) others are false. And even with analytics "false" it seems it's installed or used somewhere, I don't know ...

I've just tried your solution with Info.plist and FIREBASE_ANALYTICS_COLLECTION_ENABLED to false...and it seems do the trick... THANK YOU !!!!

lostation commented 2 years ago

Euh wait...still not working in fact... probably cached file or something... that's not fixed with set only FIREBASE_ANALYTICS_COLLECTION_ENABLED to false... It badly seems there's still a blocking issue. So until now... TrackingTransparency.requestTrackingPermission is needed to unblock push reception...

lostation commented 2 years ago

Somewhere in my logs...I've found -> 6.16.0 - [Firebase/Analytics][I-ACS023012] Analytics collection enabled even if there is also FIREBASE_ANALYTICS_COLLECTION_ENABLED to false... wtf ???

I didn't try with FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED... I will ... just to be sure.

lostation commented 2 years ago

FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED to true ... doesn't work either... : (

lostation commented 2 years ago

Another thing from logs:

1 - [I-ACS031025] Analytics screen reporting is enabled. Call +[FIRAnalytics setScreenName:setScreenClass:] to set the screen name or override the default screen class name. To disable screen reporting, set the flag FirebaseScreenReportingEnabled to NO (boolean) in the Info.plist

Ok I've added it.

2 - Don't call firebase.getCurrentPushToken() before call init({...}) method !

node_modules/nativescript-plugin-firebase/messaging/messaging.ios.js:66:0: Error in messaging.getCurrentPushToken: TypeError: null is not an object (evaluating 'FIRMessaging.messaging().FCMToken'

3 - 6.16.0 - [Firebase/Core][I-COR000003] The default Firebase app has not yet been configured. Add [FIRApp configure]; (FirebaseApp.configure() in Swift) to your application initialization. Read more: https://goo.gl/ctyzm8. 6.16.0 - [Firebase/Messaging][I-FCM001000] FIRMessaging Remote Notifications proxy enabled, will swizzle remote notification receiver handlers. If you'd prefer to manually integrate Firebase Messaging, add "FirebaseAppDelegateProxyEnabled" to your Info.plist, and set it to NO. Follow the instructions at: https://firebase.google.com/docs/cloud-messaging/ios/client#method_swizzling_in_firebase_messaging to ensure proper integration. -[NWConcrete_nw_resolver initWithEndpoint:parameters:path:log_str:] [R2] created for Hostname#2ece96df:0 using: generic, indefinite nw_path_evaluator_start [7E23D9F0-7E08-4FB7-822A-E73AA825423F Hostname#2ece96df:0 generic, indefinite] path: satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns nw_resolver_set_update_handler_block_invoke [R2] started 6.16.0 - [Firebase/Analytics][I-ACS023007] Analytics v.60202000 started 6.16.0 - [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see http://goo.gl/RfcP7r) 6.16.0 - [Firebase/Analytics][I-ACS023013] Analytics collection disabled. <----- Seems finally disabled !!!

4 - Maybe could be useful to know that there's also a registering issue following all the above stuffs ...

6.16.0 - [Firebase/Messaging][I-FCM012002] Error in application:didFailToRegisterForRemoteNotificationsWithError: aucune autorisation \M-B\M-+\M-B\240aps-environment\M-B\240\M-B\M-; valide d\M-C\M-)tect\M-C\M-)e pour l\M-b\M^@\M^Yapplication

lostation commented 2 years ago

I'me still struggling with all of that 20 days later... nothing is more unclear than all of that...Seriously it's making me crazy.

My app is using 3 differents brand or flavors.

The difference is just that it uses different sass files and target different api endpoint with env files...the rest is strictly the same for all the flavors...and it's copying etc during web pack process.

For summarize... Sometimes it works sometimes not... I've tried to make a recipe ...but it begins to be some mystical stuff...

For instance if I do the following

1 - Clean App_Resources and platforms and be sure to add into Info.plist

<key>FIREBASE_ANALYTICS_COLLECTION_ENABLED</key>
<false/>

2 - Then build in dev local to real device

tns run ios --no-hmr --env.verbose --env.sourceMap --env.configuration='dev'

... nativescript-plugin-firebase: /platforms/ios/.pluginfirebaseinfo not found, forcing prepare! nativescript-plugin-firebase: running release build or change in environment detected, forcing prepare! ...

at the end of Xcode build it shows this :

-> Unable to start application com.my.app on device 70ea3a… Try starting it manually.

sometimes it’s auto rebuilding again a second time … but not always...

Successfully installed on device with identifier '70ea3a…’. Restarting application on device 70ea3a...

Error while trying to start application com.my.app on device 70ea3a…. Error is: Could not start service com.apple.debugserver Unable to start application com.my.app on device 70ea3a…. Try starting it manually. Successfully synced application com.my.app on device 70ea3a….

-> So started app manually....and then I'm testing notifications -> it's not working : (

3 - Ok continue ... I kill the app, keep all previously builded files untouched and then manually rebuild again in same dev local to same real device

tns run ios --no-hmr --env.verbose --env.sourceMap --env.configuration='dev'

nativescript-plugin-firebase: building for same environment, not forcing prepare. <--- Maybe issue related to ? Installing pods... etc..

-> And finally testing notifications -> this time it's working ... okayyyyy ? so what's changed ?

4 - Then if it worked at previous step, I'm still keeping builded files untouched and manually rebuild in production mode and send to TestFlight for real beta tests

nativescript-plugin-firebase: running release build or change in environment detected, forcing prepare!

-> Download from testflight ... -> Test notifications -> working....

With all the previous steps, I've tried to extract a kind of logical way to reproduce when it works but it's clearly random...maybe it's ok maybe not...and I don't find any reason for that.

And ok if for the first flavor it worked...then the worst... If I change my targetted flavor...and redo all the defined steps...it's not working...at all. I can try whatever...it will not work twice this time...

Maybe it's caused by re-use the same real device id ? firebase is linked to the first tried flavor ... cache ?

Please please please @EddyVerbruggen can you try to help to debug this situation ? or point me to some advices ?

What can I do ? try ? do more ? debug ? override version ?

Before iOS v14.5...all flavors and stuffs worked perfectly... it's just completely frustrating...

And obviously with Android side it works like a charm... damned...

lostation commented 2 years ago

Ok... I've finally get the job done! Hourra... I've tried so many things that is difficult to make a conclusion.

First -> I had forgotten to add APN Key for some flavors...thus probably since apple 14.7.1 is more restrictive with permission maybe it hangs at this step...in fact surely...the registering of firebase device client shouldn't be done correctly for sure.

And second -> From a clean Platform & App_Resources folder, all files are copied at their right place... There was just a strange behavior with the firebase-copy-google-services hooks especially with the file called .nsprepareinfo and its content...

If its content is like

{ "time": "", "nativePlatformStatus": "2", "release": false, "changesRequireBuild": true, "projectFileHash": "039494b25f52255ede...", "changesRequireBuildTime": "" }

as it seems to be created during the first dev build...

Then notifications won't work on the real iPhone device.

Another interesting things ... sometimes it's auto rebuilding even if it was successful cause the .nsprepareinfo has been deleted... then after this second rebuild the file's content is becoming

{ "time": "Tue Aug 24 2021 22:12:41 GMT+0200 (heure d’été d’Europe centrale)", "nativePlatformStatus": "3", "release": false, "changesRequireBuild": true, "projectFileHash": "3bd786044b94fe47...", "changesRequireBuildTime": "Tue Aug 24 2021 22:12:41 GMT+0200 (heure d’été d’Europe centrale)" }

and then it will work with notification ... with the use of nstudio/AppTracking permission plugin -> authorized.

It's still unclear to me why there is almost same code once in After-Prepare/firebase-copy-google-services.js and also ointo before-checkForChanges.... ??? In one there is check for android stuff and into another it's check for Ios... why ?

Is there some ns lifecycles that I missed ? Or it it linked to the fact that Xcode needs some prepared files ? before and after ?

Anyway... I tweaked a little bit the after-prepare and the checkForChanges copy-google-services to always force a firebase prepare... so the .nsprepareinfo is also every time deleted... That's probably the reason why it is now auto rebuilding sometimes... That's not a problem in fact...

So to be sure that my production build will work with fireable notification -> I have to first do a dev build ...then do some tests on real device to be sure it really works...and if ok, then rebuild in prod mode keeping files as they were... Then build prod files should correctly used firebase and can be transporter to store.

Can you confirm that for IOS the Google-Plist file should only be placed into App_Resources/iOS/there ? Can you confirm that for android ...should only be into App_Resources/Android/app/there ?

And absolutely not at any other place as for instance the platform folder's root ?

In fact I think for my usage, "simple mode" with only one google config file (meaning no dev or prod extension), the hooks after-prepare and forChanges are completely not useful... All the google files are already at their right places.

Can I just remove the hooks ???

Can you also explain what's really the goal of those 2 files ?

.nsprepareinfo and .pluginfirebaseinfo

Are these files absolutely necessary somewhere or it's only used from hooks ?

Anyway... Thanks for any answer ... if any... or even with no response as usual that's ok ... I hope these experiments could be useful for someone else...

Cheers man.