Upgrade to Pro — share decks privately, control downloads, hide ads and more …

From Feature Flags to Personalisation with Fire...

From Feature Flags to Personalisation with Firebase Remote Config

I’ve been working as software engineer for about 8 years, mostly with mobile development on iOS platform. I’m also passionate in UX and I chose this topic to share with you how software engineer like me can implement more engaging user experience app with Firebase Romote Config.

Firebase Thailand

February 21, 2023
Tweet

More Decks by Firebase Thailand

Other Decks in Technology

Transcript

  1. Release and Monitor Crashlytics Performance Monitoring Test Lab Build Auth

    Cloud Functions Cloud Firestore Cloud Storage Hosting Realtime Database Engage Predictions Cloud Messaging Remote Config A/B Testing Dynamic Links In-App Messaging Analytics
  2. Dev 💻 Test ✅ ✅ ✅ Submit for review Launch

    user Mobile development process 🐞
  3. Firebase Remote Config - Update app behavior remotely - Audience

    and custom targeting - Key:Value pairs in the Cloud - No cost! Yes, it’s free.
  4. Feature flags, A/B Tests, Personalisation Version 1.1.0 Add donate feature

    Use case 1: Put new feature behind flag Donate Every penny helps Donate Version 1.0.0 Helps reduce release risks - Test with small amount of user before rollout - Kill switch £ 5 £ 10 £ 15 £ 20
  5. 2. Set up Remote Config import FirebaseRemoteConfig // initialize remote

    config let config = RemoteConfig.remoteConfig() #if DEBUG let settings = RemoteConfigSettings() settings.minimumFetchInterval = 0 // usually 12 hour caching - adjust this if needed config.configSettings = settings #endif
  6. 3. Set up default in-app values // add default config

    config.setDefaults(fromPlist: "remote_config_defaults")
  7. 4. Fetch and apply a value import FirebaseRemoteConfig struct SplashView:

    View { var body: some View { ... .onAppear { let config = RemoteConfig.remoteConfig() config.fetchAndActivate { status, error in showMainView() // TODO: log error if needed } } } } Ref: 🔗 Firebase Remote Config loading strategies
  8. 5. Use value in the UI import FirebaseRemoteConfig import FirebaseRemoteConfigSwift

    struct ContentListView: View { @RemoteConfigProperty( key: "donate_feature_enabled", fallback: false ) var donateFeatureEnabled: Bool .. Button("Donate") { donateButtonPressed() } .hiddenConditionally(isHidden: !donateFeatureEnabled) }
  9. Feature flags, A/B Tests, Personalisation Use case 2: Targeting conditions

    - Internal test - Percentage rollout Donate Dev team & Internal users Other users
  10. Targeted configurations 📦 Ready-to-use conditions: - App, platform - App

    version, browser - Langage, country - Date time - Random percentiles ✨ Google Analytics: - User property, User audience
  11. Test your parameters within dev team - Get the installation

    id to test on your device import FirebaseInstallations Installations.installations().installationID { id, error in print("installation id: \(id)") }
  12. Feature flags, A/B Tests, Personalisation Use case 3: Experiment Donate

    VS I think our donate button is very hard to see – changing position of it might help? Boss: Version 1.1.2 Experiment position of donate button Donate
  13. Firebase A/B Testing - Optimize app with multivariate experiments -

    Automatic winner determination - Integrated with Analytics, Remote Config and FCM
  14. A/B Testing: What & Why - Make data-driven decisions -

    Shift from “I think” to “I know” - Understand users opinions - Every experiment tells you something
  15. A/B Testing: What & Why - Make data-driven decisions -

    Shift from “I think” to “I know” - Understand users opinions - Every experiment tells you something
  16. Design an experiment • Goal ◦ Which position of the

    donate button will get more engage? • Variants ◦ Top vs Bottom • Targeting ◦ 20% of iOS users Donate Donate VS
  17. Log analytic events Button("Donate") { donateButtonPressed() } ... func donateButtonPressed()

    { showingDonateView.toggle() FirebaseAnalytics.Analytics.logEvent( "donate_btn_pressed", parameters: nil ) }
  18. Add config for button position ... @RemoteConfigProperty( key: "donate_button_position", fallback:

    "top" ) var donateButtonPosition: String // Button at the top Button("Donate") { donateButtonPressed() }.hiddenConditionally( isHidden: donateButtonPosition != "top" )
  19. Add config for button position ... @RemoteConfigProperty( key: "donate_button_position", fallback:

    "top" ) var donateButtonPosition: String // Button at the top ... // Button at the bottom Button("Donate") { donateButtonPressed() }.hiddenConditionally( isHidden: donateButtonPosition != "bottom" )
  20. Test your experiment import FirebaseInstallations Installations.installations().authTokenForcingRefresh(true, completion: { (result, error)

    in guard let result = result else { return } print("Installation auth token: \(result.authToken)") })
  21. Feature flags, A/B Tests, Personalisation Use case 4: Personalization (Infinite

    A/B Testing) Mate, people are having different tastes – why stick with one option that best for all? Version 1.1.2 Personalize suggested amount Every penny helps £ 5 £ 10 £ 15 £ 20 Donate Every penny helps £2.99 £4.99 £9.99 £12.99 Donate or
  22. Remote config Personalization Beta - Create several use experience alternatives

    - Machine learning to automatically provide best one to each user - ML model continuously adjusts
  23. A/B Testing • 1 best option for all • Fixed

    time window • Help on decision making • Personalized for each users • Continuous running • Optimize conversion objective Personalization
  24. Feature flags, A/B Tests, Personalisation Use case 4: Personalization (Infinite

    A/B Testing) Mate, people are having different tastes – why stick with one option that best for all? Version 1.1.2 Personalize suggested amount Every penny helps £ 5 £ 10 £ 15 £ 20 Donate Every penny helps £2.99 £4.99 £9.99 £12.99 Donate or
  25. Add config for donate amount ... @RemoteConfigProperty( key: "donate_amount", fallback:

    "5,10,15,20" ) var donateAmountsString: String var amounts: [String] { donateAmountsString.components(separatedBy: ",") } Picker( "Donate amount", selection: $selectedDonateAmountIndex ) { ForEach(0..<amounts.count, id: \.self) { Text("£\(amounts[$0])") } }
  26. That’s a wrap! • Feature flagging • Targeting conditions ◦

    Internal testing ◦ Percentage rollout • A/B Testing • Personalization @naluinui fb.com/FirebaseThailand fb.com/groups/FirebaseDevTH youtube.com/FirebaseThailand medium.com/FirebaseThailand Resources