firebase / firebase-ios-sdk

Firebase SDK for Apple App Development
https://firebase.google.com
Apache License 2.0
5.59k stars 1.46k forks source link

Forced to use FirebaseAppDelegateProxyEnabled=NO though using Firebase Cloud Messaging #12403

Open gpfister opened 7 months ago

gpfister commented 7 months ago

Description

I have been using FCM on a project, but decided to move away from it as it wasn't working with VoIP PushKit tokens.

However, I cannot get the APNS device token to be sent to the AppDelegate unless I put FirebaseAppDelegateProxyEnabled =NO in Info.plist.

I suspect this is because the Auth framework requires push notification to work for the MFA and/or Sign-in via Phone, however this is not not documented.

Reproducing the issue

On a project with Firebase SDK dependencies, without import FirebaseMessaging

Firebase SDK Version

10.21.0

Xcode Version

15.2

Installation Method

Swift Package Manager

Firebase Product(s)

App Check, Authentication, Firestore, Messaging, Storage

Targeted Platforms

iOS

Relevant Log Output

No response

If using Swift Package Manager, the project's Package.resolved

Expand Package.resolved snippet
```json { "pins" : [ { "identity" : "abseil-cpp-binary", "kind" : "remoteSourceControl", "location" : "https://github.com/google/abseil-cpp-binary.git", "state" : { "revision" : "bfc0b6f81adc06ce5121eb23f628473638d67c5c", "version" : "1.2022062300.0" } }, { "identity" : "app-check", "kind" : "remoteSourceControl", "location" : "https://github.com/google/app-check.git", "state" : { "revision" : "5746b2d35c91c50581590ed97abe4c06b5037274", "version" : "10.18.0" } }, { "identity" : "firebase-ios-sdk", "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk.git", "state" : { "revision" : "c60c958e707c50a9cf8bcb7cfd7d51c566d726c5", "version" : "10.19.1" } }, { "identity" : "googleappmeasurement", "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleAppMeasurement.git", "state" : { "revision" : "6b332152355c372ace9966d8ee76ed191f97025e", "version" : "10.17.0" } }, { "identity" : "googledatatransport", "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleDataTransport.git", "state" : { "revision" : "a732a4b47f59e4f725a2ea10f0c77e93a7131117", "version" : "9.3.0" } }, { "identity" : "googleutilities", "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleUtilities.git", "state" : { "revision" : "bc27fad73504f3d4af235de451f02ee22586ebd3", "version" : "7.12.1" } }, { "identity" : "grpc-binary", "kind" : "remoteSourceControl", "location" : "https://github.com/google/grpc-binary.git", "state" : { "revision" : "a673bc2937fbe886dd1f99c401b01b6d977a9c98", "version" : "1.49.1" } }, { "identity" : "gtm-session-fetcher", "kind" : "remoteSourceControl", "location" : "https://github.com/google/gtm-session-fetcher.git", "state" : { "revision" : "115f75e43851774934d695449a4836123c3246e1", "version" : "3.2.0" } }, { "identity" : "interop-ios-for-google-sdks", "kind" : "remoteSourceControl", "location" : "https://github.com/google/interop-ios-for-google-sdks.git", "state" : { "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", "version" : "100.0.0" } }, { "identity" : "leveldb", "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/leveldb.git", "state" : { "revision" : "9d108e9112aa1d65ce508facf804674546116d9c", "version" : "1.22.3" } }, { "identity" : "nanopb", "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/nanopb.git", "state" : { "revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692", "version" : "2.30909.0" } }, { "identity" : "promises", "kind" : "remoteSourceControl", "location" : "https://github.com/google/promises.git", "state" : { "revision" : "e70e889c0196c76d22759eb50d6a0270ca9f1d9e", "version" : "2.3.1" } }, { "identity" : "starscream", "kind" : "remoteSourceControl", "location" : "https://github.com/daltoniam/Starscream.git", "state" : { "revision" : "ac6c0fc9da221873e01bd1a0d4818498a71eef33", "version" : "4.0.6" } }, { "identity" : "swift-protobuf", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-protobuf.git", "state" : { "revision" : "65e8f29b2d63c4e38e736b25c27b83e012159be8", "version" : "1.25.2" } }, { "identity" : "webrtc-ios-sdk", "kind" : "remoteSourceControl", "location" : "https://github.com/ant-media/WebRTC-iOS-SDK", "state" : { "branch" : "master", "revision" : "cc447a4066be82c3268450779e10e7f88f5b00f6" } } ], "version" : 2 } ```

If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet
```yml Replace this line with the contents of your Podfile.lock! ```
google-oss-bot commented 7 months ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

paulb777 commented 7 months ago

Does it help to remove FirebaseMessaging as an Xcode project dependency?

Nothing except FirebaseMessaging is reading the FirebaseAppDelegateProxyEnabled flag.

rizafran commented 7 months ago

Hi @gpfister, it seems like what you're encountering is an intended behavior. Firebase Auth uses method swizzling to automatically obtain APNs token. You'll be able to obtain APNs token manually when you disable the FirebaseAppDelegateProxyEnabled flag. You may check our docs for more info.

gpfister commented 7 months ago

@rizafran, thanks for the doc, it is indeed as I suspected.

The thing that is bugging me, is that the SDK is automatically taking over the standard SDK, where actually it should be the other way around: by default it should be not swizzling (and to be fair, swizzling is not ideal, for most apps). In this case, my app is not importing FirebaseMessaging, and is not using MFA or Phone signup, only anonymous sign-in, and it took me a day to figure out because I remember that Auth was also using swizzling to handle some flows.

If I put myself in the shoes of someone new to Firebase iOS SDK, who after importing the SDK and start to implement basic authentication (like email/password), notifications suddenly stop working, and it takes several day to figure it out until they read something about an auth method they may never consider.

I would propose that the logic is inversed, and method swizzling is an opt-in feature (instead of an opt-out).

paulb777 commented 7 months ago

@gpfister Agree that if we were starting to today, the logic would be reversed. The design constraints were different when the SDKs were created.

I'll leave this open for us to consider how to make the transition.

gpfister commented 7 months ago

If I may suggest so, I would say to highlight it in the documentation and/or to generate an error when it is not set at all in the 'Info.plist' would at least force the reflection on each developer. The problem is that it took a while to figure this one out.

paulb777 commented 7 months ago

@morganchen12 Please consider updating the docs.

ggndpsingh commented 2 months ago

If someone is still active on this, it seems have gotten worse. FirebaseAppDelegateProxyEnabled is having no effect. I've spent 4 hours on it so far. I have FirebaseAppDelegateProxyEnabled set to NO in Info.plist and yet I could not figure out why didRegisterForRemoteNotificationsWithDeviceToken is not being called. Only when I removed FirebaseMessaging as a dependency did it started working. I did keep getting the console message "FIRMessaging Remote Notifications proxy enabled..." but after trying multiple types thought it was just a bug. Happening in both Xcode 15 and Xcode 16 Beta 3.