Aprende a crear Test A/B con Firebase
Aprende a crear Test A/B con Firebase

🔥 FIREBASE REMOTE CONFIGURATION - Crea Test A/B en tus apps iOS

Podemos crear Test A/B en Firebase y usar estos experimentos en nuestra app iOS. Es muy sencillo, solo tenemos que crear un experimento y asignarle una condición, si un user cumple la condición estará dentro del experimento. Mejora objetivos de tu app iOS añadiendo pequeños Test A/B.

SwiftBeta

Tabla de contenido

Firebase Remote Config en iOS. Aprende a crear Test A/B, experimentos en tu app iOS

Hoy en SwiftBeta vamos a aprender a cómo aplicar Test A/B en nuestras apps.  Aplicar estos Test A/B, estos experimentos, pueden ayudarnos a mejorar ciertas acciones dentro de nuestra app. Lo que haremos es que dependiendo de una condición en Firebase un user podrá entrar en nuestro Test A/B o no. Si entra en el experimento de nuestro Test A/B variaremos el texto de un Button en SwiftUI y sino dejaremos el texto del button que tiene por defecto. Y todo esto dependiendo de la condición que creemos con Firebase RemoteConfig.

Test A/B con dos posibles titles para un Button
Test A/B con dos posibles titles para un Button

Para ello vamos a utilizar otro producto que nos ofrece Firebase, se llama Firebase Remote Config. Si añadimos esta funcionalidad en nuestra app podemos habilitar o deshabilitar funcionalidades dentro de ella. O incluso variar algún color, texto, etc.
Imagina que quieres sacar una app como Amazon, pero no sabes si el Button de compra convergerá mejor en Azul o en Amarillo. Para ello puedes hacer un Test A/B y mostrar al 50% de users el Button de color Azul y al otro 50% mostrar el Button con el color Amarillo. Y así ver cuál gana, es decir, cuál funciona mejor.

Esta serie de experimentos, de hipotesis que tienes, las puedes aplicar al momento en tu app, sin tener que crear una nueva versión y subirla al App Store.

Añadimos FirebaseRemoteConfig en nuestro proyecto de Xcode

Lo primero de todo que vamos hacer, es lo de siempre. Nos vamos a Xcode y en  Targets -> General y nos vamos a la sección de Frameworks, Libraries and Embedded Contents y allí añadimos el framework FirebaseRemoteConfig.

Si tienes dudas o problemas, te recomiendo que eches un vistazo a mi primer posts donde hicimos toda la configuración de Firebase:

🔥 FIREBASE Tutorial iOS - Aprende a cómo integrar tu proyecto de Firebase con tu app en Xcode con Swift Package Manager
Crear un proyecto de Firebase y configura tu app en Xcode con Swift Package Manager. Una vez configurada tu app iOS podrás utilizar los productos de Firebase. Utilizamos el Property Wrapper @UIApplicationDelegateAdaptor para inicializar Firebase en tu app iOS.
Añadimos Firebase Remote Config a Xcode
Añadimos Firebase Remote Config a Xcode

Habilitamos Firebase Remote Config en Firebase

Ahora vamos a configurar Firebase Remote Config. Para ello accedemos a la sección correspondiente en la consola de Firebase. Una vez allí, pulsamos en Crear Configuración

Vamos a Firebase para crear nuestro primer experimento
Vamos a Firebase para crear nuestro primer experimento

Ahora, vamos a crear nuestra primera key, esta key será un identificador que usaremos desde dentro de nuestra app para acceder a un valor. En nuestro caso vamos a crear una Key que tendrá dos posibles valores para nuestro título de Crear Link, tendremos una condición y si se cumple se asignará al Button el título de PÚLSAME (vamos a ponerlo en mayúsculas para ver la clara diferencia entre ambos títulos) y sino se cumple se asignará el valor de Crear Link (tal y como teníamos hasta ahora)

Creamos nuestro primer experimento con una Key y un Valor
Creamos nuestro primer experimento con una Key y un Valor

Una vez hemos asignado un valor a nuestra key, con el texto Crear Link, lo que vamos hacer es pulsar el Button de Guardar. Y nos aparecerá la siguiente vista:

Listado de Test A/B que podemos usar en nuestra app iOS
Listado de Test A/B que podemos usar en nuestra app iOS

Aquí aparecerá toda la lista de keys de Remote Config que vayamos creando. Ya que en nuestra app podemos estar lanzando varios Test A/B a la vez. Vamos a la key que acabamos de crear con el nombre create_button_title y le damos a editar. Ahora lo que vamos hacer es añadir un condición para mostrar un valor del texto u otro dependiendo de si el user cae en el experimento del Test A/B o no.

Creamos la condición de nuestro experimento
Creamos la condición de nuestro experimento

La condición que vamos a añadir es muy simple, si un user entra en nuestra app tendrá un 50% de probabilidades de entrar en el experimento, si entra en el experimento se mostrará un title PÚLSAME y si no entra se mostrará otro title en nuestro Button y será Crear Link. Aquí estamos haciendo un experimento bastante simple, podríamos hacer otro de cambiar un color de fondo, el color del Button, mostrar una vista con más información en nuestra app, etc.
Una vez hemos creado una condición vamos a añadir un valor cuando un user esté dentro de esta condición.

Asignamos un valor al experimento, el user tiene un 50% de entrar en él
Asignamos un valor al experimento, el user tiene un 50% de entrar en él

Y una vez hemos añadido esta condición le damos a Guardar. Ahora vamos a publicar estos cambios para poder ir a Xcode y llamar a esta Key de nuestro Remote Config.

Publicamos el experimento para poder acceder a él desde Xcode (desde el código)
Publicamos el experimento para poder acceder a él desde Xcode (desde el código)

Configuramos Firebase RemoteConfig en Xcode

Ahora vamos a nuestra app en Xcode. Vamos a crear una clase llamada RemoteConfiguration, esta clase se va a encargar de recuperar las keys de nuestro RemoteConfig, en nuestro caso solo va a ser una create_button_title:

import Foundation
import FirebaseRemoteConfig

final class RemoteConfiguration: ObservableObject {
    @Published var buttonTitle: String = ""
    var remoteConfig: RemoteConfig
    
    init() {
        remoteConfig = RemoteConfig.remoteConfig()
        let settings = RemoteConfigSettings()
        // Tiempo mínimo hasta que volvemos a pedir al servidor el valor de nuestras Keys
        settings.minimumFetchInterval = 30
        remoteConfig.configSettings = settings
        remoteConfig.setDefaults(["create_button_title" : "Cargando..." as NSObject])
        buttonTitle = remoteConfig.configValue(forKey: "create_button_title").stringValue ?? ""
    }
    
    func fetch() {
        remoteConfig.fetchAndActivate { [weak self] success, error in
            if let error = error {
                print("Error \(error.localizedDescription)")
                return
            }
            DispatchQueue.main.async {
                self?.buttonTitle = self?.remoteConfig.configValue(forKey: "create_button_title").stringValue ?? ""
            }
        }
    
Clase que permite obtener el resultado de nuestro experimento

Una vez creada la clase RemoteConfiguration, la vamos a instanciar e inyectar una vez la app ha sido lanzada. En ReadLaterApp, en el punto de entrada de nuestra app, vamos a crear una propiedad y vamos a usar el modificador .environmentObject en la vista HomeView:

@main
struct ReadLaterApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    @StateObject var authenticationViewModel = AuthenticationViewModel()
    @StateObject var remoteConfiguration = RemoteConfiguration()
    
    var body: some Scene {
        WindowGroup {
            if let _ = authenticationViewModel.user {
                HomeView(authenticationViewModel: authenticationViewModel)
                    .environmentObject(remoteConfiguration)
            } else {
                AuthenticationView(authenticationViewModel: authenticationViewModel)
            }
        }
    }
}
Instanciamos la clase que acabamos de crear y se la inyectamos a environmentObject

Ahora, nos vamos a la vista LinkView y vamos a crear una propiedad nueva EnvironmentObject para recuperar la instancia de RemoteConfiguration que acabamos de inyectar en ReadLaterApp:

struct LinkView: View {
    @ObservedObject var linkViewModel: LinkViewModel
    @State var text: String = ""
    @EnvironmentObject var remoteConfiguration: RemoteConfiguration
    
    // código de LinkView
}
Creamos la propiedad en LinkView de tipo RemoteConfiguration

Y dentro del modificador .tasks vamos a llamar a fetch, el método que hemos creado dentro de la clase RemoteConfiguration.

        // código de LinkView
        .task {
            remoteConfiguration.fetch()
            linkViewModel.getAllLinks()
        }
Llamamos a todos nuestros experimentos usando el método fetch()

Por último, nos falta asignar el valor recibido en la key de nuestro remote config en nuestro Button de la vista LinkView.

            Button(action: {
                linkViewModel.createNewLink(fromURL: text)
            }, label: {
                Label(remoteConfiguration.buttonTitle, systemImage: "link")
            })
Asignamos la propiedad buttonTitle al Button para actualizar el título del Button cuando obtengamos la respuesta de Firebase

Compilamos nuestra app y vamos a probar

Vamos a probar nuestra app y vamos a ver en qué parte del experimento Test A/B caemos. Para hacer pruebas puedes ir borrando la app y volverla a instalar, de esta manera tendrás un 50% de entrar dentro del experimento. Realizar Test A/B con Firebase Remote Config es muy potente ya que estamos haciendo cambios en nuestra app sin tener que sacar una nueva versión y pasar el proceso de revisión.
También podríamos hacer otro ejemplo, que en lugar de cambiar el texto de un Button cambiara el color.

Conclusión

Hoy hemos aprendido a cómo hacer cambios dinámicos dentro de nuestra app según unas condiciones que apliquemos. Muy útil para ver cómo se comportan diferentes users con diferentes condiciones. Dependen cual sea nuestra acción a conseguir dentro de la app: comprar, enviar un primer mensaje, subir una foto, etc puede ayudar a mejorar nuestro funnel.

Si quieres seguir aprendiendo sobre SwiftUI, Swift, Xcode, o cualquier tema relacionado con el ecosistema Apple