firebase / firebase/firebase-ios-sdk
didRegister/didFailToRegisterForRemoteNotifications callbacks not called when FirebaseAuth is linked via SPM
- Dominant language
- C++
- Stars
- 6.7k
- Forks
- 1.8k
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 75
Description
### Description
When the FirebaseAuth library is included as a Swift Package Manager dependency in an iOS project, and FirebaseApp.configure() is called during application launch, the standard iOS AppDelegate callbacks for APNs registration (application(_:didRegisterForRemoteNotificationsWithDeviceToken:) and application(_:didFailToRegisterForRemoteNotificationsWithError:)) are never invoked.
This issue occurs even in a minimal reproduction case within the project where only FirebaseApp.configure() is called and no other Firebase APIs are used immediately.
Crucially, APNs registration succeeds (the callbacks are invoked) under the following conditions:
1. If FirebaseApp.configure() is not called.
2. If FirebaseApp.configure() is called, but the FirebaseAuth product is removed from the SPM dependencies (even if other Firebase products like FirebaseAnalytics, FirebaseFirestore, FirebaseFunctions, FirebaseStorage remain).
This suggests an issue within the initialization process triggered by the presence of the FirebaseAuth library itself, interfering with the system-level APNs registration mechanism. The problem persists even when using programmatic FirebaseOptions for configuration instead of GoogleService-Info.plist. All necessary capabilities (Push Notifications, Background Modes - Remote Notifications) and Info.plist/.entitlements entries appear correct, and APNs registration works flawlessly in a separate clean project with FirebaseAuth. The original project exhibiting this issue was also rebuilt from scratch by copying source files into a new project structure, but the problem persisted.
### Reproducing the issue
1. Create an iOS project using SwiftUI and the AppDelegate lifecycle (@UIApplicationDelegateAdaptor).
2. Add the firebase-ios-sdk Swift Package. Include at least FirebaseAnalytics and FirebaseAuth as product dependencies.
3. Set up the necessary capabilities (Push Notifications, Background Modes - Remote Notifications) and entitlements.
4. Use a minimal AppDelegate that calls FirebaseApp.configure() in didFinishLaunchingWithOptions and implements the standard push registration flow (requestAuthorization, registerForRemoteNotifications) and the two delegate callbacks (didRegister..., didFailToRegister...) with simple print statements. (See relevant log info below for example code structure).
5. Run the app on a physical device.
6. Observe that after the "Requesting APNS registration..." log, neither the success nor failure APNs delegate callbacks are ever printed.
7/ Verify: Remove only the FirebaseAuth product from the Swift Package dependencies, clean the build folder, delete derived data, restart Xcode, and run again. Observe that the didRegisterForRemoteNotificationsWithDeviceToken callback is now invoked successfully.
### Firebase SDK Version
Tested 11.12.0, 11.11.0 and 11.9.0
### Xcode Version
16.3
### Installation Method
Swift Package Manager
### Firebase Product(s)
Authentication
### Targeted Platforms
iOS
### Relevant Log Output
```shell
[Firebase/Core][I-COR000001] Configuring the default Firebase app...
[Firebase/Core][I-COR000004] Firebase App ID: 1:XXXXXXXXXX:ios:XXXXXXXXXXXXXX
[Firebase/Core][I-COR000012] Firebase Analytics enabled
[Firebase/Core][I-COR000005] The default Firebase app has been configured successfully.
[PushTest] Permission granted: true
[PushTest] Requesting APNS registration...
// <<< NO FURTHER "SUCCESS" OR "FAILED" LOGS APPEAR >>>
```
### If using Swift Package Manager, the project's Package.resolved
{
"originHash" : "c63c63846d9c539229e96de38d6af51417e28c0ee9a0bc48bd0f0f19d923c329",
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5",
"version" : "1.2024072200.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "61b85103a1aeed8218f17c794687781505fbbef5",
"version" : "11.2.0"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk.git",
"state" : {
"revision" : "fbd463894af94d90eb4d6a4e54080459a8179519",
"version" : "11.12.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "f7460ea630bddf172115c28493ae8b3798d95ce3",
"version" : "11.12.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "617af071af9aa1d6a091d59a202910ac482128f9",
"version" : "10.1.0"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "53156c7ec267db846e6b64c9f4c4e31ba4cf75eb",
"version" : "8.0.2"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "cc0001a0cf963aa40501d9c2b181e7fc9fd8ec71",
"version" : "1.69.0"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "4d70340d55d7d07cc2fdf8e8125c4c126c1d5f35",
"version" : "4.4.0"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe",
"version" : "101.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1",
"version" : "2.30910.0"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac",
"version" : "2.4.0"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "d72aed98f8253ec1aa9ea1141e28150f408cf17f",
"version" : "1.29.0"
}
}
],
"version" : 3
}
### If using CocoaPods, the project's Podfile.lock
Expand Podfile.lock snippet
```yml
Replace this line with the contents of your Podfile.lock!
```
Contributor guide
Research direction
Begin with the minimal SwiftUI AppDelegate lifecycle using @UIApplicationDelegateAdaptor, FirebaseApp.configure(), and the APNs registration callbacks described in the report. Compare initialization with FirebaseAuth present and absent, then trace the FirebaseAuth startup path; done means the success or failure callback is reliably invoked in the reported SPM setup without regressing the control case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100