I have a new feature on my iOS app that is disabled by default. To manage this, I use Firebase RemoteConfig to do this, and added new_feature_enabled = false to a config_debug.plist file. I then set this as the default using remoteConfig.setDefaults(fromPlist: "config_debug").
My app has a background task, which when upon receiving a silent push notification, it would wake up the iOS app in the background to perform some tasks.
The issue I am facing is, after I enable the new feature remotely on Firebase console (ie setting new_feature_enabled = true on the console), and trigger the silent push notification, the app wakes up but the feature is reverted to disabled mode. I then kill the app, and launched the app again, the feature then got enabled.
In other words, every time the device receives the silent push notification and wakes up in the background, the remoteConfig resets to the local config.plistfile instead of using the remote version set on Firebase console.
Code:
//In AppDelegate
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
//handle silent PN and do background tasks...
handleSilentPN(userInfo: userInfo)
completionHandler(.newData)
}
func handleSilentPN(userInfo: [AnyHashable: Any]) {
guard let scheduler = userInfo["scheduler"] as? [String: AnyObject] else {return}
guard let rootViewController = (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window?.rootViewController as? MainTabController else {
return
}
let vc = SomeController()
let controller = UINavigationController(rootViewController: vc)
rootViewController.present(controller, animated: false)
}
//At SceneDelegate
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
//Setup remote config
setupRemoteConfig()
let vc = MainTabController()
setupWindow(viewController: vc, scene: scene)
}
fileprivate func setupWindow(viewController: UIViewController, scene: UIScene) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.windowScene = windowScene
window?.rootViewController = viewController
}
func setupRemoteConfig() {
let remoteConfig = RemoteConfig.remoteConfig()
//Throttles for development to see changes frequently
#if DEBUG
let settings = RemoteConfigSettings()
settings.minimumFetchInterval = 0
remoteConfig.configSettings = settings
#endif
//Define a default setting
#if DEBUG
remoteConfig.setDefaults(fromPlist: "config_debug")
#else
remoteConfig.setDefaults(fromPlist: "config_release")
#endif
remoteConfig.fetchAndActivate { (status, error) in
if let error = error {
Log("Err setingup remote config: \(error.localizedDescription)")
}
//0: .successFetchedFromRemote
//1: .successUsingPreFetchedData
//2: .error
Log("Remote config status: \(status.rawValue)")
}
}
My code syncs RemoteConfig at SceneDelegate and ensures they are the remote version that is fetched from Firebase console. I suspected that setupRemoteConfig was called before didReceiveRemoteNotification and therefore did not sync the remote version.
I reattempted by moving setupRemoteConfig to didFinishLaunchingWithOptions and didReceiveRemoteNotification but both seems to give the same results.
I then tested which functions get called when the app wakes up in the background, and noticed that the following do not get called:
didFinishLaunchingWithOptionsapplication(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions)scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)sceneDidBecomeActive(_ scene: UIScene)
Where should I call setupRemoteConfig() so that I can maintain the remote version of the remoteConfig after receiving silent PN, and ensure that the new feature is enabled?