Skip to content

feat: Add Native Firebase Remote Config Support (Android & iOS)#37

Closed
egiray wants to merge 13 commits into
godot-x:mainfrom
egiray:feature/remote-config
Closed

feat: Add Native Firebase Remote Config Support (Android & iOS)#37
egiray wants to merge 13 commits into
godot-x:mainfrom
egiray:feature/remote-config

Conversation

@egiray
Copy link
Copy Markdown
Contributor

@egiray egiray commented Apr 21, 2026

Summary

This PR implements native Firebase Remote Config support for both Android and iOS. This is a key milestone in our modernization roadmap for the godotx-firebase extension, focusing on providing a production-grade, feature-complete native SDK for Godot 4.6+.

Key Features

  • Unified API: Synchronized methods for Android (Kotlin) and iOS (Objective-C++) exposed to GDScript.
  • Real-time Updates: Support for addOnConfigUpdateListener (Android) and addOnConfigUpdateListener (iOS) to react to config changes without polling.
  • Rich Data Support: Beyond basic types (String, Int, Bool, Float), this implementation includes a recursive JSON-to-Dictionary mapper for fetching complex configurations via get_dictionary().
  • Life-cycle Management: Proper initialization checks and listener cleanup to prevent memory leaks and crashes.
  • Enhanced Export Plugin: Automated the injection of necessary Firebase dependencies and native configurations for both platforms.

Implementation Details

  • Android: Implemented in Kotlin using the latest Firebase BOM. Includes a recursive JSON parser for nested objects/arrays.
  • iOS: Implemented in Objective-C++ with ARC. Leverages the standard Firebase iOS SDK and maps native types to Godot Variants.
  • UI: Added a dedicated RemoteConfigView to the Test Harness for real-time verification of fetch/activate cycles.

Dependencies & Context

Important

This PR is part of a layered contribution stack. It is built on top of:

  1. PR chore: Shared foundation fixes and Test Harness UI improvements #34 (Shared Foundation / Base Setup)
  2. PR feat: implementation of modular Test Harness UI and native signal refinements #36 (Shared UI / Dashboard)

It is recommended to merge #34 and #36 sequentially before this PR, as this branch includes the necessary infrastructure from both.

Full Roadmap

This contribution is structured in five modular phases:

  1. Phase 1: Shared Foundation (PR chore: Shared foundation fixes and Test Harness UI improvements #34) ✅
  2. Phase 2: Dashboard UI Infrastructure (PR feat: implementation of modular Test Harness UI and native signal refinements #36) ✅
  3. Phase 3: Remote Config Module (This PR) ✅
  4. Phase 4: Enhanced Messaging: Extending native modules to include the full data payload dictionary.
  5. Phase 5: Analytics Extension: Adding user properties, screen tracking, and predefined game events.

Testing Performed

  • Android: Verified on physical device (Pixel/Samsung) with real-time updates triggered from the Firebase Console.
  • iOS: Verified on physical iPhone with Xcode 15+.
  • Edge Cases: Verified behavior when Firebase is not initialized and handled fetch throttling gracefully.

egiray added 12 commits April 18, 2026 23:39
- FirebaseRemoteConfigPlugin.kt: fetch_and_activate, typed getters
  (string/int/float/bool/dictionary), set_defaults, throttle detection,
  real-time listener via addOnConfigUpdateListener
- export_plugin.gd: enable_remote_config option + AAR bundling
- Full Gradle build setup mirroring existing module structure
task.result on Android returns a Boolean: true means new values were
fetched from the server, false means cached values were returned. Map
this to FETCH_CACHED (1) instead of treating both as FETCH_SUCCESS (0).

Updated enum to match iOS FIRRemoteConfigFetchAndActivateStatus:
  SUCCESS=0, CACHED=1, FAILURE=2, THROTTLED=3
…nfig plugin

- Add initialize() method matching upstream plugin pattern; Remote Config
  now requires explicit init after FirebaseCore, preventing crashes when
  google-services.json is missing or misconfigured
- Store ConfigUpdateListenerRegistration and expose remove_config_update_listener()
- Fix get_string to use VALUE_SOURCE_STATIC check like all other getters
- Add remote_config_initialized signal
…sons

Missing error signal meant GDScript had no way to know why initialize()
failed or when the real-time listener died. Now emits error codes matching
the pattern used by Analytics and Messaging plugins.
…heck

This signal is iOS-only (APN = Apple Push Notifications). Connecting it
unconditionally on Android throws a script error that halts plugin
initialization for all subsequent plugins in the same function.
Crashlytics requires the com.google.firebase.crashlytics Gradle plugin to
be applied at build time so it can inject a build UUID into the APK. Without
it the app crashes at launch with 'The Crashlytics build ID is missing'.

The export plugin now patches settings.gradle and build.gradle automatically
when firebase/enable_crashlytics is true, so users do not have to edit the
Android build template manually.
@paulocoutinhox
Copy link
Copy Markdown
Contributor

paulocoutinhox commented Apr 23, 2026

When you finish, add a message here

The gradle com.google.gms.google-services part is already in the documentation. We can't put it fixed because depends of the version the user wanna use in their Android project and compatible with their plugins/tools. It also depends of gradle or kts.

@toannth
Copy link
Copy Markdown

toannth commented Apr 28, 2026

Sounds good. This fix #32

@egiray
Copy link
Copy Markdown
Contributor Author

egiray commented Apr 28, 2026

I am closing this PR. Since I've updated and made a bigger PR:

PR38

@egiray egiray closed this Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants