0

I need to test some features of my app with just a previously selected group of users.

I created an Audience where user_id exactly matches 123456. 123456 being my own ID.

In Remote Config I created a Condition that matches users in the Audience above.

Then I created a parameter in Remote Config called feature_available and for the condition, I set a return value of true. The Default value is false.

In my app I set up Firebase:

    FIRApp.configure()

    let remoteConfig = FIRRemoteConfig.remoteConfig()
    if let remoteConfigSettings = FIRRemoteConfigSettings(developerModeEnabled: false) {
        remoteConfig.configSettings = remoteConfigSettings
    }
    remoteConfig.setDefaultsFromPlistFileName("FirebaseRemoteConfigDefaults")

And set the user ID:

    FIRAnalytics.setUserID("123456")

Then I fetch from Firebase:

    var expirationDuration: Double
    // If in developer mode cacheExpiration is set to 0 so each fetch will retrieve values from the server.
    expirationDuration = remoteConfig.configSettings.isDeveloperModeEnabled ? 0 : 3600

    remoteConfig.fetch(withExpirationDuration: TimeInterval(expirationDuration)) { (status, error) -> Void in
        if status == .success {
            remoteConfig.activateFetched()
        } else {
            assertionFailure("Firebase config not fetched. Error \(error!.localizedDescription)")
        }
    }

The last thing I do is to get the value from Firebase and check if I have the feature enable:

    let featureIsAvailable = remoteConfig["feature_available"].boolValue
    if featureIsAvailable { ... }

The problem is that every single time the value returns from Firebase it is false and I can't manage to get it to return the correct value that matches that Audience I created. I also tried to do it setting a user property instead of using setUserID() and had the same result. Any suggestions?

Tchelow
  • 593
  • 4
  • 15

2 Answers2

0

I've run into similar issues before, sometimes it can take a while for the fetch to finish. The check if the feature is available needs to be done when the config is successfully fixed. Something like this hopefully works for you as well:

var featureIsAvailable : Bool?

override func viewDidLoad() {
    super.viewDidLoad()

    configureRemoteConfig()
    fetchConfig()      
}

func configureRemoteConfig() {
    remoteConfig = FIRRemoteConfig.remoteConfig()
    // Create Remote Config Setting to enable developer mode.
    // Fetching configs from the server is normally limited to 5 requests per hour.
    // Enabling developer mode allows many more requests to be made per hour, so developers
    // can test different config values during development.
    let remoteConfigSettings = FIRRemoteConfigSettings(developerModeEnabled: true)
    remoteConfig.configSettings = remoteConfigSettings!
    remoteConfig.setDefaultsFromPlistFileName("RemoteConfigDefaults")
}

func fetchConfig() {
    var expirationDuration: Double = 3600
    // If in developer mode cacheExpiration is set to 0 so each fetch will retrieve values from
    // the server.
    if (self.remoteConfig.configSettings.isDeveloperModeEnabled) {
        expirationDuration = 0
    }

    // cacheExpirationSeconds is set to cacheExpiration here, indicating that any previously
    // fetched and cached config would be considered expired because it would have been fetched
    // more than cacheExpiration seconds ago. Thus the next fetch would go to the server unless
    // throttling is in progress. The default expiration duration is 43200 (12 hours).
    remoteConfig.fetch(withExpirationDuration: expirationDuration) { (status, error) in
        if (status == .success) {
            print("Config fetched!")
            self.remoteConfig.activateFetched()

            let featureIsAvailable = self.remoteConfig["feature_available"]

            if (featureIsAvailable.source != .static) {
                self.featureIsAvailable = featureIsAvailable.boolValue
                print("should the feature be available?", featureIsAvailable!)
            }
        } else {
            print("Config not fetched")
            print("Error \(error)")
        }
        self.checkIfFeatureIsAvailable()
    }
}

func checkIfFeatureIsAvailable() {
    if featureIsAvailable == false {
        // Don't show new feature
    } else {
        // Show new feature
    }
}
Jordi Bruin
  • 1,588
  • 1
  • 11
  • 20
  • Thanks Jordi, but that's basically what I'm doing. When my fetch succeeds, the values that should be received as `true` are all `false`. TBH, I don't believe it's something with my code, but something with Firebase that returns the wrong value for the Audience. – Tchelow Nov 30 '16 at 22:11
  • @Tchelow i must have read the question incorrectly them, my bad! – Jordi Bruin Dec 01 '16 at 00:07
0

I sent an email to the Firebase team requesting support and they told me that the issue was a bug in Xcode 8(.0 and .1) using Swift. Updating to the latest version released today, 8.2, fixed the issue.

Tchelow
  • 593
  • 4
  • 15