Description
Description
We have an iOS app that allows users to pick target environment at runtime. Each environment has the each own plist
file, ie GoogleService-Info-Staging.plist or GoogleService-Info-Prod.plist.
Whenever user switch environment, I teardown the FIrebase
private(set) var remoteConfig: RemoteConfig?
public func tearDownFirebase() async {
if let app = FirebaseApp.app() {
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(false)
remoteConfig = nil
await app.delete()
}
}
Then reinitiate the Firebase and RemoteConfig
public init(plist: Plist) {
if FirebaseApp.app() == nil {
guard let plistPath = Bundle.module.path(forResource: plist, ofType: "plist"),
let firebaseOptions = FirebaseOptions(contentsOfFile: plistPath)
else {
BP.Log.log(Events.firebaseStartedWithoutOptions(env: plist))
FirebaseApp.configure()
return
}
FirebaseApp.configure(options: firebaseOptions)
}
remoteConfig = RemoteConfig.remoteConfig()
}
public func startRemoteConfig(environment: EnvironmentName) async throws
-> RemoteConfigFetchStatus
{
guard let remoteConfig else { throw BPFirebaseError.remoteConfigInstance }
remoteConfig.setDefaults(RemoteConfigKey.defaults as? [String: NSObject])
remoteConfig.configSettings = RemoteConfigSettings()
let expirationDuration =
self.isDeveloperMode(environment: environment)
? 0
: RemoteConfigValues.shared.cacheExpiration
do {
let result = try await remoteConfig.fetch(withExpirationDuration: expirationDuration)
try await remoteConfig.activate()
return result
} catch {
throw BPFirebaseError.remoteConfigFetch
}
}
I am able to see that the .plist
file for the target environment is being properly passed in and invoked. The FirebaseApp.app() also has different address after the environment is switched.
The problem is with the remote config. It always shows the first values being pulled. So for example, if I start with "Staging" env, and then trying to switch to "Production, after the re-initialization process is complete, it keeps showing Staging remote config values.
Questions:
• Did I do the correct steps and procedures to teardown
the Firebase?
• Is there specific steps I need to perform to "reset" the previous RemoteConfig.remoteConfig()
to make sure it pulls in the correct value when users switch environment?
• Does Remote Config support switching environment at runtime?
Reproducing the issue
• Make sure you have different .plist
file for each target environment
• Allow users to switch environments
• When the switch is requested, make sure the proper plist
is used to create the FirebaseApp.app()
• Check that remote config pulls in the right values for a specific environment
Firebase SDK Version
10.24.0
Xcode Version
15.3
Installation Method
Swift Package Manager
Firebase Product(s)
Crashlytics, Firestore, Remote Config
Targeted Platforms
iOS
Relevant Log Output
-- INITIAL ENVIRONMENT --
BP.app/BPFirebase_BPFirebase.bundle/GoogleService-Info-NPD.plist
2024-04-30 21:42:45.944081-0600 BP[74735:36948440] [Firebase/Crashlytics] Version 10.24.0
RemoteConfig activated: Optional(<FIRRemoteConfig: 0x600002aff960>) | app: <FIRApp: 0x600000082c70>
RemoteConfig fetched
-- SWITCH TO STAGING ENVIRONMENT --
BP.app/BPFirebase_BPFirebase.bundle/GoogleService-Info-Staging.plist
RemoteConfig activated: Optional(<FIRRemoteConfig: 0x600002aff960>) | app: <FIRApp: 0x60000023a580>
RemoteConfig fetched
If using Swift Package Manager, the project's Package.resolved
Expand Package.resolved
snippet
{
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "748c7837511d0e6a507737353af268484e1745e2",
"version" : "1.2024011601.1"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "c218c2054299b15ae577e818bbba16084d3eabe6",
"version" : "10.18.2"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk.git",
"state" : {
"revision" : "42eae77a0af79e9c3f41df04a23c76f05cfdda77",
"version" : "10.24.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "51ba746a9d51a4bd0774b68499b0c73ef6e8570d",
"version" : "10.24.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "a637d318ae7ae246b02d7305121275bc75ed5565",
"version" : "9.4.0"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "26c898aed8bed13b8a63057ee26500abbbcb8d55",
"version" : "7.13.1"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359",
"version" : "1.62.2"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "9534039303015a84837090d20fa21cae6e5eadb6",
"version" : "3.3.2"
}
},
{
"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" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac",
"version" : "2.4.0"
}
},
{
"identity" : "servicecontext",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ribtiago/ServiceContext.git",
"state" : {
"revision" : "f3ebe4fd8374ecdb8e31201d493772dc6eaab7c3",
"version" : "2.0.1"
}
},
{
"identity" : "snapkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SnapKit/SnapKit",
"state" : {
"revision" : "d458564516e5676af9c70b4f4b2a9178294f1bc6",
"version" : "5.0.1"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb",
"version" : "1.1.0"
}
},
{
"identity" : "swift-package-manager-google-mobile-ads",
"kind" : "remoteSourceControl",
"location" : "https://github.com/googleads/swift-package-manager-google-mobile-ads.git",
"state" : {
"revision" : "5ff977255c2ba5844e7e9da779f1f2a5a00e0028",
"version" : "11.2.0"
}
},
{
"identity" : "swift-package-manager-google-user-messaging-platform",
"kind" : "remoteSourceControl",
"location" : "https://github.com/googleads/swift-package-manager-google-user-messaging-platform.git",
"state" : {
"revision" : "cfe8b2ae16b9bc81f4cdf1d1a12a01a452489c32",
"version" : "2.3.0"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "9f0c76544701845ad98716f3f6a774a892152bcb",
"version" : "1.26.0"
}
},
{
"identity" : "swiftuibackports",
"kind" : "remoteSourceControl",
"location" : "https://github.com/shaps80/SwiftUIBackports.git",
"state" : {
"revision" : "dfc492b9907d1c9b78f3ef928add759b798c464d",
"version" : "1.0.9"
}
},
{
"identity" : "swiftuiextras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ribtiago/SwiftUIExtras.git",
"state" : {
"revision" : "b40c865b2756a0c07145e065f078d5a4c591d08f",
"version" : "1.9.3"
}
}
],
"version" : 2
}
If using CocoaPods, the project's Podfile.lock
Expand Podfile.lock
snippet
Replace this line with the contents of your Podfile.lock!