From 48c846998ca420a6715e35e62055db86dfd8bded Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:57:40 +0000 Subject: [PATCH 1/2] Implement UseUserAccessGroup for Firebase Auth C++ SDK This commit introduces the `UseUserAccessGroup` method to the Firebase Authentication C++ SDK. This method allows developers to specify a user access group for iCloud keychain access on iOS. It calls the underlying Objective-C method `[FIRAuth useUserAccessGroup:error:]`. On other platforms (Desktop, Android), this method is a no-op and returns `kAuthErrorNone` as the feature is iOS-specific. Key changes: - Added `UseUserAccessGroup` declaration to `firebase::auth::Auth` in `auth/src/include/firebase/auth.h` with Doxygen comments. - Implemented the iOS-specific logic in `auth/src/ios/auth_ios.mm`, including error handling and string conversion. - Added a stub implementation in `auth/src/desktop/auth_desktop.cc` for non-iOS platforms. --- auth/src/desktop/auth_desktop.cc | 5 +++++ auth/src/include/firebase/auth.h | 15 +++++++++++++++ auth/src/ios/auth_ios.mm | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/auth/src/desktop/auth_desktop.cc b/auth/src/desktop/auth_desktop.cc index dc9aca2950..e934013c64 100644 --- a/auth/src/desktop/auth_desktop.cc +++ b/auth/src/desktop/auth_desktop.cc @@ -575,6 +575,11 @@ void Auth::UseEmulator(std::string host, uint32_t port) { auth_impl->assigned_emulator_url.append(std::to_string(port)); } +AuthError Auth::UseUserAccessGroup(const char* access_group) { + // This is an iOS-only feature. No-op on other platforms. + return kAuthErrorNone; +} + void InitializeTokenRefresher(AuthData* auth_data) { auto auth_impl = static_cast(auth_data->auth_impl); auth_impl->token_refresh_thread.Initialize(auth_data); diff --git a/auth/src/include/firebase/auth.h b/auth/src/include/firebase/auth.h index f6809c4a57..7ad013e4c7 100644 --- a/auth/src/include/firebase/auth.h +++ b/auth/src/include/firebase/auth.h @@ -517,6 +517,21 @@ class Auth { /// not available on the current device. static Auth* GetAuth(App* app, InitResult* init_result_out = nullptr); + /// @brief Specifies a user access group for iCloud keychain access. + /// + /// This method is only functional on iOS. On other platforms, it is a no-op + /// and will always return `kAuthErrorNone`. + /// + /// If you are using iCloud keychain synchronization, you will need to call + /// this method to set the user access group. + /// + /// @param[in] access_group The user access group to use. Set to `nullptr` or + /// an empty string to use the default access group. + /// + /// @return `kAuthErrorNone` on success, or an AuthError code if an error + /// occurred. + AuthError UseUserAccessGroup(const char* access_group); + private: /// @cond FIREBASE_APP_INTERNAL friend class ::firebase::App; diff --git a/auth/src/ios/auth_ios.mm b/auth/src/ios/auth_ios.mm index a0292ba3b8..f449735670 100644 --- a/auth/src/ios/auth_ios.mm +++ b/auth/src/ios/auth_ios.mm @@ -608,5 +608,23 @@ void DisableTokenAutoRefresh(AuthData *auth_data) {} void InitializeTokenRefresher(AuthData *auth_data) {} void DestroyTokenRefresher(AuthData *auth_data) {} +AuthError Auth::UseUserAccessGroup(const char* access_group_str) { + if (!auth_data_) { + return kAuthErrorUninitialized; + } + NSString* access_group_ns_str = nil; + if (access_group_str != nullptr && strlen(access_group_str) > 0) { + access_group_ns_str = [NSString stringWithUTF8String:access_group_str]; + } + + NSError* error = nil; + BOOL success = [AuthImpl(auth_data_) useUserAccessGroup:access_group_ns_str error:&error]; + if (success) { + return kAuthErrorNone; + } else { + return AuthErrorFromNSError(error); + } +} + } // namespace auth } // namespace firebase From 24b857160b5e4749cb45cf6be0838ac105dfac0c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 18:17:58 +0000 Subject: [PATCH 2/2] Address review feedback for UseUserAccessGroup This commit addresses feedback from the pull request review for the UseUserAccessGroup feature: - Added a stub implementation for Android in `auth_android.cc`. - Updated iOS implementation in `auth_ios.mm` to pass an empty NSString (`@""`) to the native SDK if an empty C++ string is provided. `nullptr` still results in `nil` being passed. - Updated Doxygen comments in `auth.h` to reflect the iOS behavior for `nullptr` and empty string inputs more accurately. - Investigated potential NSError codes for the underlying iOS SDK method. Confirmed that `FIRAuthErrorCodeKeychainError` is the most relevant documented error, and it is already correctly handled by the existing C++ error mapping. --- auth/src/android/auth_android.cc | 5 +++++ auth/src/include/firebase/auth.h | 11 ++++++++--- auth/src/ios/auth_ios.mm | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index e0a9a669cb..335a9e5173 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -676,5 +676,10 @@ void DisableTokenAutoRefresh(AuthData* auth_data) {} void InitializeTokenRefresher(AuthData* auth_data) {} void DestroyTokenRefresher(AuthData* auth_data) {} +AuthError Auth::UseUserAccessGroup(const char* access_group) { + // This is an iOS-only feature. No-op on other platforms. + return kAuthErrorNone; +} + } // namespace auth } // namespace firebase diff --git a/auth/src/include/firebase/auth.h b/auth/src/include/firebase/auth.h index 7ad013e4c7..ce363424af 100644 --- a/auth/src/include/firebase/auth.h +++ b/auth/src/include/firebase/auth.h @@ -525,11 +525,16 @@ class Auth { /// If you are using iCloud keychain synchronization, you will need to call /// this method to set the user access group. /// - /// @param[in] access_group The user access group to use. Set to `nullptr` or - /// an empty string to use the default access group. + /// @param[in] access_group The user access group to use. + /// - On iOS, if `nullptr` is provided, `nil` will be passed to the + /// underlying SDK, typically resetting to the default or app's main + /// access group. + /// - On iOS, if an empty string (`""`) is provided, an empty `NSString` + /// will be passed to the underlying SDK. + /// - On other platforms, this parameter is ignored. /// /// @return `kAuthErrorNone` on success, or an AuthError code if an error - /// occurred. + /// occurred (iOS only). AuthError UseUserAccessGroup(const char* access_group); private: diff --git a/auth/src/ios/auth_ios.mm b/auth/src/ios/auth_ios.mm index f449735670..78746c391e 100644 --- a/auth/src/ios/auth_ios.mm +++ b/auth/src/ios/auth_ios.mm @@ -613,7 +613,7 @@ void DestroyTokenRefresher(AuthData *auth_data) {} return kAuthErrorUninitialized; } NSString* access_group_ns_str = nil; - if (access_group_str != nullptr && strlen(access_group_str) > 0) { + if (access_group_str != nullptr) { access_group_ns_str = [NSString stringWithUTF8String:access_group_str]; }