Swift/iOS - Firebase Remote Config fetch values never completes
Asked Answered
H

3

8

Below is a class implemented to fetch remote config values from the Firebase console, however when calling fetch cloud values, the completion block never executes (i.e. If I break in the completion block, Xcode never breaks). All documentation seems to be outdated now and I can't see what I am doing wrong.

@objc class RemoteConfigValues: NSObject {

    @objc static let sharedInstance = RemoteConfigValues()

    private override init() {
        super.init()
        let settings = RemoteConfigSettings()

        //WARNING THIS IS FOR DEBUG ONLY
        settings.minimumFetchInterval = 0
        RemoteConfig.remoteConfig().configSettings = settings
        loadDefaultValues()
        fetchCloudValuesWith(fetchInterval: 0.0)
    }

    func loadDefaultValues() {
        let appDefaults: [String: Any?] = [
            RemoteConfigKeys.senseAdType.rawValue: String("A"),
            RemoteConfigKeys.sensePromotionButton.rawValue: String("BUY NOW")
        ]
        RemoteConfig.remoteConfig().setDefaults(appDefaults as? [String: NSObject])
    }

    func getInstanceIDToken() {
        InstanceID.instanceID().instanceID { (result, error) in
          if let error = error {
            print("Error fetching remote instance ID: \(error)")
          } else if let result = result {
            print("Remote instance ID token: \(result.token)")
          }
        }
    }

    func fetchCloudValues() {
        RemoteConfig.remoteConfig().fetchAndActivate { (status, error) in
            if let error = error {
                print("Uh-oh. Got an error fetching remote values \(error)")
                return
            }
            print("Retrieved values from the cloud!")
        }
    }

    func fetchCloudValuesWith(fetchInterval: Double) {
        RemoteConfig.remoteConfig().fetch(withExpirationDuration: fetchInterval) { status, error in

            if let error = error {
                print("Uh-oh. Got an error fetching remote values \(error)")
                return
            }

            RemoteConfig.remoteConfig().activate { (error) in
                print("Uh-oh. Got an error fetching remote values \(error?.localizedDescription ?? "")")
            }
            print("Retrieved values from the cloud!")
        }
    }

}

Below are the logs that are printing to the console for Firebase/RemoteConfig

2020-06-11 10:16:20.061816+0100 MyApp[67337:10404626] 6.12.0 - [Firebase/RemoteConfig][I-RCN000062] Loading database at path /Users/dominicbryan/Library/Developer/CoreSimulator/Devices/481BF064-0BC7-404E-836F-A0AB58FD8900/data/Containers/Data/Application/77B9DD80-FFF4-4354-8B30-23E39C794861/Library/Application Support/Google/RemoteConfig/RemoteConfig.sqlite3
2020-06-11 10:16:20.064711+0100 MyApp[67337:10404626] 6.12.0 - [Firebase/RemoteConfig]2020-06-11 10:16:20.065426+0100 MyApp[67337:10404579] <NSProgress: 0x600000f5c5a0> : Parent: 0x0 (portion: 0) / Fraction completed: 1.0000 / Completed: 2203 of 2203
2020-06-11 10:16:20.066622+0100 MyApp[67337:10404626] 6.12.0 - [Firebase/RemoteConfig][I-RCN000039] Starting requesting token.
2020-06-11 10:16:21.164733+0100 MyApp[67337:10404579] 6.12.0 - [Firebase/RemoteConfig][I-RCN000022] Success to get iid : fqcuK-XSZsU.
2020-06-11 10:16:21.166088+0100 MyApp[67337:10404579] 6.12.0 - [Firebase/RemoteConfig][I-RCN000024] Success to get device authentication ID: 5**************7, security token: 7***************8.
2020-06-11 10:16:21.166737+0100 MyApp[67337:10404579] 6.12.0 - [Firebase/RemoteConfig][I-RCN000060] Fetch with user properties completed.
Hydrophobic answered 9/6, 2020 at 15:52 Comment(3)
Does my answer helped you to fix your problem? if so, kindly accept it so that other also benefit from it.Limen
I have the same issue, I had FirebaseApp.configure() in AppDelegate. On another viewcontroller I called remoteConfig.fetch() and the callback never fired!Unsparing
Did you manage to fix it?Tully
T
1

Use your func fetchCloudValuesWith(fetchInterval: Double) instead of using fetchAndActivate:

remoteConfig.fetch(withExpirationDuration: 0) { [weak self] (status, error) in
    //Do your stuffs    
}
Tesch answered 10/6, 2020 at 12:4 Comment(1)
I have updated my answer to show that I am using the fetchCloudValuesWith(fetchInterval: Double). But again the completion is never calledHydrophobic
H
1

Anyone coming here to look for an answer, I worked out that Firebase pod was being used as a dynamic library in my main project as well as one of the modules I created. This duplicated the Firebase logic and causes it to do nothing.

Hydrophobic answered 15/10, 2020 at 14:26 Comment(1)
Same or me. It should be noted that the pod in question was FirebaseAnalytics. There are a few Firebase pods that are static.Thesda
L
0

Create a singleton variable for RemoteConfig instead of Directly using RemoteConfig.remoteConfig()

As mentioned in official firebase document mentioned here

Create the singleton Remote Config object, as shown in the following example:

Here is the code for it.

private var remoteConfig : RemoteConfig!

override func viewDidLoad() {
    super.viewDidLoad()
    remoteConfig = RemoteConfig.remoteConfig()
    let settings = RemoteConfigSettings()
    settings.minimumFetchInterval = 0
    remoteConfig.configSettings = settings

    NotificationCenter.default.addObserver(self, selector: #selector(fg), name: UIApplication.willEnterForegroundNotification, object: nil)

    // Do any additional setup after loading the view.
}

 override func viewDidAppear(_ animated: Bool) {
    print(#function)
    fetchData()
}
func fetchData() {

    remoteConfig.fetch { (status, error) in

        if status == .success {
            print("Config fetched!")
            self.remoteConfig.activate() { (error) in
                // ...
            }
        } else {
            print("Config not fetched")
            print("Error: \(error?.localizedDescription ?? "No error available.")")
        }
        self.doSomething()
    }
}

func doSomething() {
    key1 = remoteConfig[key1].stringValue
    key2 = remoteConfig[key2].boolValue  }

Hope this helps.

Limen answered 17/6, 2020 at 4:28 Comment(3)
This doesn't make any difference unfortunately. You are just creating a new pointer to the same RemoteConfig reference.Hydrophobic
the code that I pasted worked for me. So thought of posting it for you. @dLimen
Okay thank you for the answer, I won't be selecting it as the answer to my question unfortunatelyHydrophobic

© 2022 - 2024 — McMap. All rights reserved.