diff --git a/packages/firebase_auth/firebase_auth/example/pubspec.yaml b/packages/firebase_auth/firebase_auth/example/pubspec.yaml index c894e45410e2..74b7be58641f 100644 --- a/packages/firebase_auth/firebase_auth/example/pubspec.yaml +++ b/packages/firebase_auth/firebase_auth/example/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: firebase_messaging: ^16.1.1 flutter: sdk: flutter - flutter_facebook_auth: ^7.0.1 + flutter_facebook_auth: ^7.1.5 flutter_signin_button: ^2.0.0 google_sign_in: ^6.1.0 google_sign_in_dartio: ^0.3.0 diff --git a/packages/firebase_auth/firebase_auth/windows/firebase_auth_plugin.cpp b/packages/firebase_auth/firebase_auth/windows/firebase_auth_plugin.cpp index 8986fb26e613..5a4f1bf27faf 100644 --- a/packages/firebase_auth/firebase_auth/windows/firebase_auth_plugin.cpp +++ b/packages/firebase_auth/firebase_auth/windows/firebase_auth_plugin.cpp @@ -53,6 +53,9 @@ void FirebaseAuthPlugin::RegisterWithRegistrar( FirebaseAuthHostApi::SetUp(registrar->messenger(), plugin.get()); FirebaseAuthUserHostApi::SetUp(registrar->messenger(), plugin.get()); + RegisterFlutterFirebasePlugin("plugins.flutter.io/firebase_auth", + plugin.get()); + registrar->AddPlugin(std::move(plugin)); binaryMessenger = registrar->messenger(); @@ -1283,4 +1286,35 @@ void FirebaseAuthPlugin::RevokeTokenWithAuthorizationCode( nullptr)); } +flutter::EncodableMap FirebaseAuthPlugin::GetPluginConstantsForFirebaseApp( + const firebase::App& app) { + flutter::EncodableMap constants; + + Auth* auth = Auth::GetAuth(const_cast(&app)); + firebase::auth::User user = auth->current_user(); + + if (user.is_valid()) { + PigeonUserDetails userDetails = ParseUserDetails(user); + flutter::EncodableList userDetailsList; + userDetailsList.push_back( + flutter::EncodableValue(userDetails.user_info().ToEncodableList())); + userDetailsList.push_back( + flutter::EncodableValue(userDetails.provider_data())); + constants[flutter::EncodableValue("APP_CURRENT_USER")] = + flutter::EncodableValue(userDetailsList); + } + + std::string lang = auth->language_code(); + if (!lang.empty()) { + constants[flutter::EncodableValue("APP_LANGUAGE_CODE")] = + flutter::EncodableValue(lang); + } + + return constants; +} + +void FirebaseAuthPlugin::DidReinitializeFirebaseCore() { + // No-op for now. Could be used to reset cached auth instances. +} + } // namespace firebase_auth_windows diff --git a/packages/firebase_auth/firebase_auth/windows/firebase_auth_plugin.h b/packages/firebase_auth/firebase_auth/windows/firebase_auth_plugin.h index 419c83236fb6..a75ff33e6cf5 100644 --- a/packages/firebase_auth/firebase_auth/windows/firebase_auth_plugin.h +++ b/packages/firebase_auth/firebase_auth/windows/firebase_auth_plugin.h @@ -16,6 +16,7 @@ #include "firebase/auth.h" #include "firebase/auth/types.h" #include "firebase/future.h" +#include "firebase_core/flutter_firebase_plugin.h" #include "messages.g.h" using firebase::auth::AuthError; @@ -24,7 +25,8 @@ namespace firebase_auth_windows { class FirebaseAuthPlugin : public flutter::Plugin, public FirebaseAuthHostApi, - public FirebaseAuthUserHostApi { + public FirebaseAuthUserHostApi, + public FlutterFirebasePlugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); @@ -180,6 +182,11 @@ class FirebaseAuthPlugin : public flutter::Plugin, const AuthPigeonFirebaseApp& app, const std::string& authorization_code, std::function reply)> result) override; + // FlutterFirebasePlugin methods. + flutter::EncodableMap GetPluginConstantsForFirebaseApp( + const firebase::App& app) override; + void DidReinitializeFirebaseCore() override; + private: static flutter::BinaryMessenger* binaryMessenger; }; diff --git a/packages/firebase_core/firebase_core/windows/CMakeLists.txt b/packages/firebase_core/firebase_core/windows/CMakeLists.txt index 40a880ba426b..1df3eeb43f59 100644 --- a/packages/firebase_core/firebase_core/windows/CMakeLists.txt +++ b/packages/firebase_core/firebase_core/windows/CMakeLists.txt @@ -65,6 +65,8 @@ list(APPEND PLUGIN_SOURCES "firebase_core_plugin.h" "messages.g.cpp" "messages.g.h" + "flutter_firebase_plugin_registry.h" + "flutter_firebase_plugin_registry.cpp" ) # Read version from pubspec.yaml diff --git a/packages/firebase_core/firebase_core/windows/firebase_core_plugin.cpp b/packages/firebase_core/firebase_core/windows/firebase_core_plugin.cpp index b544e85ecb36..0644dc8cf7ea 100644 --- a/packages/firebase_core/firebase_core/windows/firebase_core_plugin.cpp +++ b/packages/firebase_core/firebase_core/windows/firebase_core_plugin.cpp @@ -9,6 +9,7 @@ #include "firebase/app.h" #include "firebase_core/plugin_version.h" +#include "flutter_firebase_plugin_registry.h" #include "messages.g.h" // For getPlatformVersion; remove unless needed for your plugin implementation. @@ -95,7 +96,8 @@ CoreFirebaseOptions optionsFromFIROptions(const firebase::AppOptions& options) { // Convert a firebase::App to CoreInitializeResponse CoreInitializeResponse AppToCoreInitializeResponse(const App& app) { - flutter::EncodableMap plugin_constants; + flutter::EncodableMap plugin_constants = + FlutterFirebasePluginRegistry::GetPluginConstantsForFirebaseApp(app); CoreInitializeResponse response = CoreInitializeResponse( app.name(), optionsFromFIROptions(app.options()), plugin_constants); return response; @@ -116,7 +118,11 @@ void FirebaseCorePlugin::InitializeApp( void FirebaseCorePlugin::InitializeCore( std::function reply)> result) { - // TODO: Missing function to get the list of currently initialized apps + if (coreInitialized) { + FlutterFirebasePluginRegistry::DidReinitializeFirebaseCore(); + } + coreInitialized = true; + std::vector initializedApps; std::vector all_apps = App::GetApps(); for (const App* app : all_apps) { diff --git a/packages/firebase_core/firebase_core/windows/firebase_core_plugin_c_api.cpp b/packages/firebase_core/firebase_core/windows/firebase_core_plugin_c_api.cpp index d8215be27a40..3615a59064b6 100644 --- a/packages/firebase_core/firebase_core/windows/firebase_core_plugin_c_api.cpp +++ b/packages/firebase_core/firebase_core/windows/firebase_core_plugin_c_api.cpp @@ -10,6 +10,7 @@ #include #include "firebase_core_plugin.h" +#include "flutter_firebase_plugin_registry.h" void FirebaseCorePluginCApiRegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar) { @@ -17,3 +18,9 @@ void FirebaseCorePluginCApiRegisterWithRegistrar( flutter::PluginRegistrarManager::GetInstance() ->GetRegistrar(registrar)); } + +void RegisterFlutterFirebasePlugin(const std::string& channel_name, + FlutterFirebasePlugin* plugin) { + firebase_core_windows::FlutterFirebasePluginRegistry::RegisterPlugin( + channel_name, plugin); +} diff --git a/packages/firebase_core/firebase_core/windows/flutter_firebase_plugin_registry.cpp b/packages/firebase_core/firebase_core/windows/flutter_firebase_plugin_registry.cpp new file mode 100644 index 000000000000..3d4c1d80fe21 --- /dev/null +++ b/packages/firebase_core/firebase_core/windows/flutter_firebase_plugin_registry.cpp @@ -0,0 +1,39 @@ +// Copyright 2023, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#include "flutter_firebase_plugin_registry.h" + +namespace firebase_core_windows { + +std::unordered_map& +FlutterFirebasePluginRegistry::GetRegisteredPlugins() { + static std::unordered_map plugins; + return plugins; +} + +void FlutterFirebasePluginRegistry::RegisterPlugin( + const std::string& channel_name, FlutterFirebasePlugin* plugin) { + GetRegisteredPlugins()[channel_name] = plugin; +} + +flutter::EncodableMap +FlutterFirebasePluginRegistry::GetPluginConstantsForFirebaseApp( + const firebase::App& app) { + flutter::EncodableMap all_constants; + for (const auto& entry : GetRegisteredPlugins()) { + flutter::EncodableMap plugin_constants = + entry.second->GetPluginConstantsForFirebaseApp(app); + all_constants[flutter::EncodableValue(entry.first)] = + flutter::EncodableValue(plugin_constants); + } + return all_constants; +} + +void FlutterFirebasePluginRegistry::DidReinitializeFirebaseCore() { + for (const auto& entry : GetRegisteredPlugins()) { + entry.second->DidReinitializeFirebaseCore(); + } +} + +} // namespace firebase_core_windows diff --git a/packages/firebase_core/firebase_core/windows/flutter_firebase_plugin_registry.h b/packages/firebase_core/firebase_core/windows/flutter_firebase_plugin_registry.h new file mode 100644 index 000000000000..a6c5ddb3a068 --- /dev/null +++ b/packages/firebase_core/firebase_core/windows/flutter_firebase_plugin_registry.h @@ -0,0 +1,43 @@ +// Copyright 2023, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#ifndef FLUTTER_FIREBASE_PLUGIN_REGISTRY_H_ +#define FLUTTER_FIREBASE_PLUGIN_REGISTRY_H_ + +#include + +#include +#include + +#include "firebase/app.h" +#include "include/firebase_core/flutter_firebase_plugin.h" + +namespace firebase_core_windows { + +// Static registry that collects plugin constants from all registered Firebase +// plugins during initializeCore, mirroring Android's +// FlutterFirebasePluginRegistry. +class FlutterFirebasePluginRegistry { + public: + // Registers a plugin with the given channel name. + static void RegisterPlugin(const std::string& channel_name, + FlutterFirebasePlugin* plugin); + + // Collects constants from all registered plugins for the given app. + // Returns a map keyed by channel name, with each value being the plugin's + // constants map. + static flutter::EncodableMap GetPluginConstantsForFirebaseApp( + const firebase::App& app); + + // Notifies all registered plugins that Firebase core was re-initialized. + static void DidReinitializeFirebaseCore(); + + private: + static std::unordered_map& + GetRegisteredPlugins(); +}; + +} // namespace firebase_core_windows + +#endif // FLUTTER_FIREBASE_PLUGIN_REGISTRY_H_ diff --git a/packages/firebase_core/firebase_core/windows/include/firebase_core/firebase_core_plugin_c_api.h b/packages/firebase_core/firebase_core/windows/include/firebase_core/firebase_core_plugin_c_api.h index 68f3d1d314d6..93023e96a4c3 100644 --- a/packages/firebase_core/firebase_core/windows/include/firebase_core/firebase_core_plugin_c_api.h +++ b/packages/firebase_core/firebase_core/windows/include/firebase_core/firebase_core_plugin_c_api.h @@ -12,6 +12,8 @@ #include #include +#include "flutter_firebase_plugin.h" + #ifdef FLUTTER_PLUGIN_IMPL #define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) #else @@ -21,4 +23,10 @@ FLUTTER_PLUGIN_EXPORT void FirebaseCorePluginCApiRegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar); +// Registers a FlutterFirebasePlugin so that its constants are collected during +// Firebase.initializeApp(). The channel_name should match the Dart +// MethodChannel name (e.g. "plugins.flutter.io/firebase_auth"). +FLUTTER_PLUGIN_EXPORT void RegisterFlutterFirebasePlugin( + const std::string& channel_name, FlutterFirebasePlugin* plugin); + #endif // FLUTTER_PLUGIN_FIREBASE_CORE_PLUGIN_C_API_H_ diff --git a/packages/firebase_core/firebase_core/windows/include/firebase_core/flutter_firebase_plugin.h b/packages/firebase_core/firebase_core/windows/include/firebase_core/flutter_firebase_plugin.h new file mode 100644 index 000000000000..ade655151cda --- /dev/null +++ b/packages/firebase_core/firebase_core/windows/include/firebase_core/flutter_firebase_plugin.h @@ -0,0 +1,29 @@ +// Copyright 2023, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#ifndef FLUTTER_FIREBASE_PLUGIN_H_ +#define FLUTTER_FIREBASE_PLUGIN_H_ + +#include + +#include "firebase/app.h" + +// Abstract interface mirroring Android's FlutterFirebasePlugin.java and iOS's +// FLTFirebasePlugin.h. Each Firebase plugin implements this to provide initial +// constants (e.g. current user) during Firebase.initializeApp(). +class FlutterFirebasePlugin { + public: + virtual ~FlutterFirebasePlugin() {} + + // Returns a map of plugin-specific constants for the given Firebase app. + // Called synchronously during initializeCore to populate pluginConstants. + virtual flutter::EncodableMap GetPluginConstantsForFirebaseApp( + const firebase::App& app) = 0; + + // Called when Firebase core is re-initialized, allowing plugins to reset + // their state. + virtual void DidReinitializeFirebaseCore() = 0; +}; + +#endif // FLUTTER_FIREBASE_PLUGIN_H_