Codelab de Firebase para Android: Crea un chat amigable

1. Descripción general

captura de pantalla

Imagen: App de Chat fácil de usar

Te damos la bienvenida al codelab Friendly Chat. En este codelab, aprenderás a usar la plataforma Firebase para crear una app de chat en Android.

Qué aprenderás

  • Cómo usar Firebase Authentication para permitir el acceso de los usuarios
  • Cómo sincronizar datos con Firebase Realtime Database
  • Cómo almacenar archivos binarios en Cloud Storage para Firebase
  • Cómo usar Firebase Local Emulator Suite para desarrollar una app para Android con Firebase.

Requisitos

  • La versión más reciente de Android Studio
  • Un Android Emulator con Android 5.0 o versiones posteriores
  • Node.js 10 o una versión posterior (para usar Emulator Suite).
  • Java 8 o superior. Para instalar Java, sigue estas instrucciones. Para comprobar tu versión, ejecuta java -version.
  • Conocer el lenguaje de programación Kotlin

2. Obtén el código de muestra

Clona el repositorio

Clona el repositorio de GitHub a partir de la línea de comandos:

$ git clone https://github.com/firebase/codelab-friendlychat-android

Cómo importar a Android Studio

En Android Studio, selecciona File > Open y, luego, selecciona el directorio build-android-start ( carpeta_android_studio) del directorio en el que descargaste el código de muestra.

Ahora, deberías tener el proyecto build-android-start abierto en Android Studio. Si ves una advertencia sobre la falta de un archivo google-services.json, no te preocupes. Se agregará en un paso posterior.

Verifica las dependencias

En este codelab, ya se agregaron todas las dependencias que necesitarás, pero es importante que comprendas cómo agregar el SDK de Firebase a tu app:

build.gradle.kts

plugins {
    id("com.android.application") version "8.0.0" apply false
    id("com.android.library") version "8.0.0" apply false
    id("org.jetbrains.kotlin.android") version "1.8.20" apply false

    // The google-services plugin is required to parse the google-services.json file
    id("com.google.gms.google-services") version "4.3.15" apply false
}

app/build.gradle.kts

plugins {
    id("com.android.application")
    id("kotlin-android")
    id("com.google.gms.google-services")
}

android {
    // ...
}

dependencies {
    // ...

    // Google Sign In SDK
    implementation("com.google.android.gms:play-services-auth:20.5.0")

    // Firebase SDK
    implementation(platform("com.google.firebase:firebase-bom:32.0.0"))
    implementation("com.google.firebase:firebase-database-ktx")
    implementation("com.google.firebase:firebase-storage-ktx")
    implementation("com.google.firebase:firebase-auth-ktx")

    // Firebase UI Library
    implementation("com.firebaseui:firebase-ui-auth:8.0.2")
    implementation("com.firebaseui:firebase-ui-database:8.0.2")
}

3. Instala Firebase CLI

En este codelab, usarás Firebase Emulator Suite para emular localmente Firebase Auth, Realtime Database y Cloud Storage. Esto proporciona un entorno de desarrollo local seguro, rápido y sin costo para compilar tu app.

Instala Firebase CLI

Primero, debes instalar Firebase CLI. Si usas macOS o Linux, puedes ejecutar el siguiente comando cURL:

curl -sL https://firebase.tools | bash

Si usas Windows, lee las instrucciones de instalación para obtener un objeto binario independiente o instalarlo a través de npm.

Una vez que hayas instalado la CLI, ejecutar firebase --version debería informar una versión de 9.0.0 o superior:

$ firebase --version
9.0.0

Acceder

Ejecuta firebase login para conectar la CLI a tu Cuenta de Google. Se abrirá una ventana nueva del navegador para completar el proceso de acceso. Asegúrate de elegir la misma cuenta que usaste cuando creaste el proyecto de Firebase.

4. Conéctate a Firebase Emulator Suite

Cómo iniciar los emuladores

En la terminal, ejecuta el siguiente comando desde la raíz del directorio local codelab-friendlychat-android:

firebase emulators:start --project=demo-friendlychat-android

Deberías ver algunos registros como este. Los valores del puerto se definieron en el archivo firebase.json, que se incluyó en el código de muestra clonado.

$ firebase emulators:start --project=demo-friendlychat-android
i  emulators: Starting emulators: auth, database, storage
i  emulators: Detected demo project ID "demo-friendlychat-android", emulated services will use a demo configuration and attempts to access non-emulated services for this project will fail.
i  database: Database Emulator logging to database-debug.log
i  ui: Emulator UI logging to ui-debug.log

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://localhost:4000                │
└─────────────────────────────────────────────────────────────┘

┌────────────────┬────────────────┬────────────────────────────────┐
│ Emulator       │ Host:Port      │ View in Emulator UI            │
├────────────────┼────────────────┼────────────────────────────────┤
│ Authentication │ localhost:9099 │ http://localhost:4000/auth     │
├────────────────┼────────────────┼────────────────────────────────┤
│ Database       │ localhost:9000 │ http://localhost:4000/database │
├────────────────┼────────────────┼────────────────────────────────┤
│ Storage        │ localhost:9199 │ http://localhost:4000/storage  │
└────────────────┴────────────────┴────────────────────────────────┘
  Emulator Hub running at localhost:4400
  Other reserved ports: 4500

Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.

Ve a http://localhost:4000 en tu navegador web para ver la IU de Firebase Emulator Suite:

Página principal de la IU de Emulator Suite

Deja el comando emulators:start ejecutándose durante el resto del codelab.

Conecta tu app

En Android Studio, abre MainActivity.kt y agrega el siguiente código dentro del método onCreate:

// When running in debug mode, connect to the Firebase Emulator Suite.
// "10.0.2.2" is a special IP address which allows the Android Emulator
// to connect to "localhost" on the host computer. The port values (9xxx)
// must match the values defined in the firebase.json file.
if (BuildConfig.DEBUG) {
    Firebase.database.useEmulator("10.0.2.2", 9000)
    Firebase.auth.useEmulator("10.0.2.2", 9099)
    Firebase.storage.useEmulator("10.0.2.2", 9199)
}

5. Ejecuta la app de partida

Agrega google-services.json

Si quieres que tu app para Android se conecte a Firebase, debes agregar un archivo google-services.json en la carpeta app de tu proyecto de Android. Para los fines de este codelab, proporcionamos un archivo JSON de prueba que te permitirá conectarte a Firebase Emulator Suite.

Copia el archivo mock-google-services.json en la carpeta build-android-start/app como google-services.json:

cp mock-google-services.json build-android-start/app/google-services.json

En el paso final de este codelab, aprenderás a crear un proyecto real y una app de Firebase para Android, de modo que puedas reemplazar este archivo JSON de prueba con tu propia configuración.

Ejecuta la app

Ahora que importaste el proyecto a Android Studio y agregaste un archivo JSON de configuración de Firebase, podrás ejecutar la app por primera vez.

  1. Inicia Android Emulator.
  2. En Android Studio, haz clic en Run ( ejecutar) en la barra de herramientas.

La app debería iniciarse en Android Emulator. En este punto, deberías ver una lista de mensajes vacía, por lo que no podrás enviar ni recibir mensajes. En el siguiente paso de este codelab, autenticarás a los usuarios para que puedan usar Friendly Chat.

6. Habilitar la autenticación.

Esta app usará Firebase Realtime Database para almacenar todos los mensajes de chat. Sin embargo, antes de agregar datos, debemos asegurarnos de que la app sea segura y de que solo los usuarios autenticados puedan publicar mensajes. En este paso, habilitaremos Firebase Authentication y configuraremos las reglas de seguridad de Realtime Database.

Agrega la funcionalidad básica de acceso

A continuación, agregaremos un código básico de Firebase Authentication a la app para detectar usuarios y, luego, implementar una pantalla de acceso.

Verificar usuario actual

Primero, agrega la siguiente variable de instancia a la clase MainActivity.kt:

MainActivity.kt

// Firebase instance variables
private lateinit var auth: FirebaseAuth

Ahora, modifiquemos MainActivity para enviar al usuario a la pantalla de acceso cada vez que abra la app y no esté autenticado. Agrega lo siguiente al método onCreate() después de adjuntar binding a la vista:

MainActivity.kt

// Initialize Firebase Auth and check if the user is signed in
auth = Firebase.auth
if (auth.currentUser == null) {
    // Not signed in, launch the Sign In activity
    startActivity(Intent(this, SignInActivity::class.java))
    finish()
    return
}

También queremos verificar si el usuario accedió durante onStart():

MainActivity.kt

public override fun onStart() {
    super.onStart()
    // Check if user is signed in.
    if (auth.currentUser == null) {
        // Not signed in, launch the Sign In activity
        startActivity(Intent(this, SignInActivity::class.java))
        finish()
        return
    }
}

Luego, implementa los métodos getUserPhotoUrl() y getUserName() para mostrar la información adecuada sobre el usuario de Firebase autenticado actualmente:

MainActivity.kt

private fun getPhotoUrl(): String? {
    val user = auth.currentUser
    return user?.photoUrl?.toString()
}

private fun getUserName(): String? {
    val user = auth.currentUser
    return if (user != null) {
        user.displayName
    } else ANONYMOUS
}

Luego, implementa el método signOut() para controlar el botón de salida:

MainActivity.kt

private fun signOut() {
    AuthUI.getInstance().signOut()
    startActivity(Intent(this, SignInActivity::class.java))
    finish()
}

Ahora tenemos toda la lógica implementada para enviar al usuario a la pantalla de acceso cuando sea necesario. A continuación, debemos implementar la pantalla de acceso para autenticar correctamente a los usuarios.

Implementa la pantalla de acceso

Abre el archivo SignInActivity.kt. Aquí, se utiliza un botón de acceso simple para iniciar la autenticación. En esta sección, usarás FirebaseUI para implementar la lógica de acceso.

Agrega una variable de instancia de Auth en la clase SignInActivity debajo del comentario // Firebase instance variables:

SignInActivity.kt.

// Firebase instance variables
private lateinit var auth: FirebaseAuth

Luego, edita el método onCreate() para inicializar Firebase de la misma manera que lo hiciste en MainActivity:

SignInActivity.kt.

// Initialize FirebaseAuth
auth = Firebase.auth

Agrega un campo ActivityResultLauncher a SignInActivity:

SignInActivity.kt.

// ADD THIS
private val signIn: ActivityResultLauncher<Intent> =
        registerForActivityResult(FirebaseAuthUIActivityResultContract(), this::onSignInResult)

override fun onCreate(savedInstanceState: Bundle?) {
    // ...
}

A continuación, edita el método onStart() para iniciar el flujo de acceso de FirebaseUI:

SignInActivity.kt.

public override fun onStart() {
    super.onStart()

    // If there is no signed in user, launch FirebaseUI
    // Otherwise head to MainActivity
    if (Firebase.auth.currentUser == null) {
        // Sign in with FirebaseUI, see docs for more details:
        // https://firebase.google.com/docs/auth/android/firebaseui
        val signInIntent = AuthUI.getInstance()
                .createSignInIntentBuilder()
                .setLogo(R.mipmap.ic_launcher)
                .setAvailableProviders(listOf(
                        AuthUI.IdpConfig.EmailBuilder().build(),
                        AuthUI.IdpConfig.GoogleBuilder().build(),
                ))
                .build()

        signIn.launch(signInIntent)
    } else {
        goToMainActivity()
    }
}

A continuación, implementa el método onSignInResult para controlar el resultado de acceso. Si el resultado del acceso fue exitoso, continúa con MainActivity:

SignInActivity.kt.

private fun onSignInResult(result: FirebaseAuthUIAuthenticationResult) {
    if (result.resultCode == RESULT_OK) {
        Log.d(TAG, "Sign in successful!")
        goToMainActivity()
    } else {
        Toast.makeText(
                this,
                "There was an error signing in",
                Toast.LENGTH_LONG).show()

        val response = result.idpResponse
        if (response == null) {
            Log.w(TAG, "Sign in canceled")
        } else {
            Log.w(TAG, "Sign in error", response.error)
        }
    }
}

Listo. Implementaste la autenticación con FirebaseUI en pocas llamadas de método, sin necesidad de administrar ninguna configuración del servidor.

Prueba tu trabajo

Ejecuta la app en Android Emulator. Deberías ir de inmediato a la pantalla de acceso. Presiona el botón Acceder con correo electrónico y, luego, crea una cuenta. Si todo se implementó correctamente, deberías recibir la pantalla de mensajes.

Después de acceder, abre la IU de Firebase Emulator Suite en tu navegador y haz clic en la pestaña Authentication para ver la primera cuenta de usuario que accedió.

7. Lea los mensajes

En este paso, agregaremos funcionalidad para leer y mostrar mensajes almacenados en Realtime Database.

Importa mensajes de muestra

  1. En la IU de Firebase Emulator Suite, selecciona la pestaña Realtime Database.
  2. Arrastra y suelta el archivo initial_messages.json de tu copia local del repositorio del codelab en el visor de datos.

Ahora deberías tener algunos mensajes en el nodo messages de la base de datos.

Lee datos

Sincronizar mensajes

En esta sección, agregamos código que sincroniza los mensajes recién agregados a la IU de la app de la siguiente manera:

  • Inicializar Firebase Realtime Database y agregar un objeto de escucha para controlar los cambios realizados en los datos
  • Actualizando el adaptador RecyclerView para que se muestren los mensajes nuevos.
  • Agrega las variables de la instancia de Database con tus otras variables de instancia de Firebase en la clase MainActivity:

Actividad.kt

// Firebase instance variables
// ...
private lateinit var db: FirebaseDatabase
private lateinit var adapter: FriendlyMessageAdapter

Modifica el método onCreate() de MainActivity en el comentario // Initialize Realtime Database and FirebaseRecyclerAdapter con el código que se define a continuación. Este código agrega todos los mensajes existentes de Realtime Database y, luego, detecta las nuevas entradas secundarias en la ruta de acceso messages de Firebase Realtime Database. Agrega un nuevo elemento a la IU para cada mensaje:

MainActivity.kt

// Initialize Realtime Database
db = Firebase.database
val messagesRef = db.reference.child(MESSAGES_CHILD)

// The FirebaseRecyclerAdapter class and options come from the FirebaseUI library
// See: https://github.com/firebase/FirebaseUI-Android
val options = FirebaseRecyclerOptions.Builder<FriendlyMessage>()
    .setQuery(messagesRef, FriendlyMessage::class.java)
    .build()
adapter = FriendlyMessageAdapter(options, getUserName())
binding.progressBar.visibility = ProgressBar.INVISIBLE
manager = LinearLayoutManager(this)
manager.stackFromEnd = true
binding.messageRecyclerView.layoutManager = manager
binding.messageRecyclerView.adapter = adapter

// Scroll down when a new message arrives
// See MyScrollToBottomObserver for details
adapter.registerAdapterDataObserver(
    MyScrollToBottomObserver(binding.messageRecyclerView, adapter, manager)
)

A continuación, en la clase FriendlyMessageAdapter.kt, implementa el método bind() dentro de la clase interna MessageViewHolder():

FriendlyMessageAdapter.kt

inner class MessageViewHolder(private val binding: MessageBinding) : ViewHolder(binding.root) {
    fun bind(item: FriendlyMessage) {
        binding.messageTextView.text = item.text
        setTextColor(item.name, binding.messageTextView)

        binding.messengerTextView.text = if (item.name == null) ANONYMOUS else item.name
        if (item.photoUrl != null) {
            loadImageIntoView(binding.messengerImageView, item.photoUrl!!)
        } else {
            binding.messengerImageView.setImageResource(R.drawable.ic_account_circle_black_36dp)
        }
    }
    ...
}

También debemos mostrar mensajes que sean imágenes, por lo que también debemos implementar el método bind() dentro de la clase interna ImageMessageViewHolder():

FriendlyMessageAdapter.kt

inner class ImageMessageViewHolder(private val binding: ImageMessageBinding) :
    ViewHolder(binding.root) {
    fun bind(item: FriendlyMessage) {
        loadImageIntoView(binding.messageImageView, item.imageUrl!!)

        binding.messengerTextView.text = if (item.name == null) ANONYMOUS else item.name
        if (item.photoUrl != null) {
            loadImageIntoView(binding.messengerImageView, item.photoUrl!!)
        } else {
            binding.messengerImageView.setImageResource(R.drawable.ic_account_circle_black_36dp)
        }
    }
}

Por último, regresa a MainActivity, comienza a escuchar actualizaciones de Firebase Realtime Database y deja de hacerlo. Actualiza los métodos onPause() y onResume() en MainActivity como se muestra a continuación:

MainActivity.kt

public override fun onPause() {
    adapter.stopListening()
    super.onPause()
}

public override fun onResume() {
    super.onResume()
    adapter.startListening()
}

Prueba la sincronización de mensajes

  1. Haz clic en Run ( ejecutar).
  2. En la IU de Emulator Suite, regresa a la pestaña Realtime Database y agrega un mensaje nuevo de forma manual. Confirma que el mensaje aparezca en la app para Android:

Felicitaciones, acabas de agregar una base de datos en tiempo real a tu app.

8. Enviar mensajes

Implementa el envío de mensajes de texto

En esta sección, agregarás la posibilidad de que los usuarios de la app envíen mensajes de texto. El siguiente fragmento de código detecta eventos de clic en el botón de envío, crea un nuevo objeto FriendlyMessage con el contenido del campo de mensaje y envía el mensaje a la base de datos. El método push() agrega un ID generado automáticamente a la ruta de acceso del objeto enviado. Estos IDs son secuenciales, lo que garantiza que los nuevos mensajes se agreguen al final de la lista.

Actualiza el objeto de escucha de clics del botón de envío en el método onCreate() de la clase MainActivity. Este código ya se encuentra en la parte inferior del método onCreate(). Actualiza el cuerpo de onClick() para que coincida con el siguiente código:

MainActivity.kt

// Disable the send button when there's no text in the input field
// See MyButtonObserver for details
binding.messageEditText.addTextChangedListener(MyButtonObserver(binding.sendButton))

// When the send button is clicked, send a text message
binding.sendButton.setOnClickListener {
    val friendlyMessage = FriendlyMessage(
        binding.messageEditText.text.toString(),
        getUserName(),
        getPhotoUrl(),
        null /* no image */
    )
    db.reference.child(MESSAGES_CHILD).push().setValue(friendlyMessage)
    binding.messageEditText.setText("")
}

Implementa el envío de mensajes con imágenes

En esta sección, agregarás la capacidad para que los usuarios de la app envíen mensajes de imagen. Para crear un mensaje de imagen, sigue estos pasos:

  • Seleccionar imagen
  • Cómo controlar la selección de imágenes
  • Escribe un mensaje de imagen temporal en Realtime Database
  • Comenzar a subir la imagen seleccionada
  • Actualizar la URL del mensaje de imagen a la de la imagen subida una vez que se complete la carga

Seleccionar imagen

Para agregar imágenes, este codelab usa Cloud Storage para Firebase. Cloud Storage es un buen lugar para almacenar los datos binarios de tu app.

Controla la selección de imágenes y escribe el mensaje temporal

Una vez que el usuario selecciona una imagen, se inicia la selección de imágenes Intent. Esto ya está implementado en el código al final del método onCreate(). Cuando finaliza, llama al método onImageSelected() de MainActivity. Con el fragmento de código que aparece a continuación, escribirás un mensaje con una URL de imagen temporal a la base de datos que indique que se está subiendo la imagen.

MainActivity.kt

private fun onImageSelected(uri: Uri) {
    Log.d(TAG, "Uri: $uri")
    val user = auth.currentUser
    val tempMessage = FriendlyMessage(null, getUserName(), getPhotoUrl(), LOADING_IMAGE_URL)
    db.reference
            .child(MESSAGES_CHILD)
            .push()
            .setValue(
                    tempMessage,
                    DatabaseReference.CompletionListener { databaseError, databaseReference ->
                        if (databaseError != null) {
                            Log.w(
                                    TAG, "Unable to write message to database.",
                                    databaseError.toException()
                            )
                            return@CompletionListener
                        }

                        // Build a StorageReference and then upload the file
                        val key = databaseReference.key
                        val storageReference = Firebase.storage
                                .getReference(user!!.uid)
                                .child(key!!)
                                .child(uri.lastPathSegment!!)
                        putImageInStorage(storageReference, uri, key)
                    })
}

Subir imagen y actualizar mensaje

Agrega el método putImageInStorage() a MainActivity. Se llama en onImageSelected() para iniciar la carga de la imagen seleccionada. Una vez que se complete la carga, actualizarás el mensaje para que use la imagen adecuada.

Actividad.kt

private fun putImageInStorage(storageReference: StorageReference, uri: Uri, key: String?) {
    // First upload the image to Cloud Storage
    storageReference.putFile(uri)
        .addOnSuccessListener(
            this
        ) { taskSnapshot -> // After the image loads, get a public downloadUrl for the image
            // and add it to the message.
            taskSnapshot.metadata!!.reference!!.downloadUrl
                .addOnSuccessListener { uri ->
                    val friendlyMessage =
                        FriendlyMessage(null, getUserName(), getPhotoUrl(), uri.toString())
                    db.reference
                        .child(MESSAGES_CHILD)
                        .child(key!!)
                        .setValue(friendlyMessage)
                }
        }
        .addOnFailureListener(this) { e ->
            Log.w(
                TAG,
                "Image upload task was unsuccessful.",
                e
            )
        }
}

Pruebe enviar mensajes

  1. En Android Studio, haz clic en el botón ejecutarRun.
  2. En Android Emulator, ingresa un mensaje y, luego, presiona el botón de envío. El nuevo mensaje debería verse en la IU de la app y en la IU de Firebase Emulator Suite.
  3. En Android Emulator, presiona la imagen "+" para seleccionar una imagen de tu dispositivo. El mensaje nuevo debe aparecer primero con una imagen de marcador de posición y, luego, con la imagen seleccionada cuando se complete la carga. El nuevo mensaje también debería estar visible en la IU de Emulator Suite, específicamente como un objeto en la pestaña de Realtime Database y como un BLOB en la pestaña Almacenamiento.

9. ¡Felicitaciones!

Acabas de compilar una aplicación de chat en tiempo real con Firebase.

Qué aprendiste

  • Firebase Authentication
  • Firebase Realtime Database
  • Cloud Storage para Firebase

A continuación, usa lo que aprendiste en este codelab para agregar Firebase a tu propia app para Android. Para obtener más información sobre Firebase, visita firebase.google.com.

Si quieres aprender a configurar un proyecto real de Firebase y usar recursos reales de Firebase (en lugar de un proyecto de demostración y solo recursos emulados), continúa con el siguiente paso.

Nota: Incluso después de configurar un proyecto real de Firebase y, especialmente cuando comienzas a compilar una app real, te recomendamos usar Firebase Local Emulator Suite para el desarrollo y las pruebas.

10. Opcional: Crea y configura un proyecto de Firebase

En este paso, crearás un proyecto real de Firebase y una app de Firebase para Android a fin de usarlos con este codelab. También agregarás la configuración específica de Firebase de tu app. Por último, configurarás recursos reales de Firebase para usar con tu app.

Crea un proyecto de Firebase

  1. En el navegador, ve a Firebase console.
  2. Selecciona Agregar proyecto.
  3. Selecciona o ingresa un nombre de proyecto. Puedes usar el nombre que quieras.
  4. En este codelab, no necesitas Google Analytics, por lo que puedes omitir la habilitación para tu proyecto.
  5. Haz clic en Crear proyecto. Cuando tu proyecto esté listo, haz clic en Continuar.

Agrega Firebase al proyecto de Android

Antes de comenzar este paso, obtén el hash SHA1 de tu app. Ejecuta el siguiente comando desde tu directorio local build-android-start para determinar el SHA1 de tu clave de depuración:

./gradlew signingReport

Store: /Users/<username>/.android/debug.keystore
Alias: AndroidDebugKey
MD5: A5:88:41:04:8F:06:59:6A:AE:33:76:87:AA:AD:19:23
SHA1: A7:89:F5:06:A8:07:A1:22:EC:90:6A:A6:EA:C3:D4:8B:3A:30:AB:18
SHA-256: 05:A2:2A:35:EE:F2:51:23:72:4D:72:67:A5:6A:8A:58:22:2C:00:A6:AB:F6:45:D5:A1:82:D8:90:A4:69:C8:FE
Valid until: Wednesday, August 10, 2044

Deberías ver un resultado como el anterior. La línea importante es el hash SHA1. Si no puedes encontrar tu hash SHA1, consulta esta página para obtener más información.

Regresa a Firebase console y sigue estos pasos para registrar tu proyecto de Android con el de Firebase:

  1. En la pantalla de descripción general del proyecto nuevo, haz clic en el ícono de Android para iniciar el flujo de trabajo de configuración: Agregar app para Android.
  2. En la siguiente pantalla, ingresa com.google.firebase.codelab.friendlychat como nombre del paquete para tu app.
  3. Haz clic en Registrar app y, luego, en Descargar google-services.json para descargar el archivo de configuración de Firebase.
  4. Copia el archivo google-services.json en el directorio app de tu proyecto de Android.
  5. Omite los próximos pasos que se muestran en el flujo de trabajo de configuración de la consola (ya se realizaron por ti en el proyecto build-android-start).
  6. Sincroniza tu proyecto con archivos Gradle a fin de asegurarte de que todas las dependencias estén disponibles para tu app. En la barra de herramientas de Android Studio, selecciona File > Sync Project with Gradle Files. Es posible que también debas ejecutar Build/Clean Project y Build/Rebuild Project para que se apliquen los cambios de configuración.

Configure Firebase Authentication

Para que tu app pueda acceder a las APIs de Firebase Authentication en nombre de tus usuarios, debes habilitar Firebase Authentication y los proveedores de acceso que quieres usar en tu app.

  1. En Firebase console, selecciona Authentication en el panel de navegación de la izquierda.
  2. Selecciona la pestaña Método de acceso.
  3. Haz clic en Correo electrónico/Contraseña y, luego, habilita el interruptor (azul).
  4. Haz clic en Google, habilita el interruptor (azul) y establece un correo electrónico de asistencia para el proyecto.

Si, más adelante en este codelab, recibes errores con el mensaje "CONFIGURATION_NOT_FOUND", regresa a este paso y vuelve a verificar tu trabajo.

Configura Realtime Database

La app de este codelab almacena mensajes de chat en Firebase Realtime Database. En esta sección, crearemos una base de datos y configuraremos su seguridad con un lenguaje de configuración JSON llamado reglas de seguridad de Firebase.

  1. En Firebase console, selecciona Realtime Database en el panel de navegación de la izquierda.
  2. Haz clic en Crear base de datos para crear una instancia nueva de Realtime Database. Cuando se te solicite, selecciona la región us-central1 y, luego, haz clic en Siguiente.
  3. Cuando se te pregunten sobre las reglas de seguridad, elige modo bloqueado y, luego, haz clic en Habilitar.
  4. Una vez creada la instancia de base de datos, selecciona la pestaña Reglas y, luego, actualiza la configuración de reglas con lo siguiente:
     {
       "rules": {
         "messages": {
           ".read": "auth.uid != null",
           ".write": "auth.uid != null"
         }
       }
     }
    

Para obtener más información sobre cómo funcionan las reglas de seguridad (incluida la documentación sobre la variable "auth"), consulta la documentación sobre seguridad de Realtime Database.

Configura Cloud Storage para Firebase

  1. En Firebase console, selecciona Storage en el panel de navegación de la izquierda.
  2. Haz clic en Comenzar para habilitar Cloud Storage en tu proyecto.
  3. Sigue los pasos que se indican en el cuadro de diálogo para configurar tu bucket con los valores predeterminados sugeridos.

Conéctate a los recursos de Firebase

En un paso anterior de este codelab, agregaste lo siguiente a MainActivity.kt. Este bloque condicional conectó tu proyecto de Android a Firebase Emulator Suite.

// REMOVE OR DISABLE THIS
if (BuildConfig.DEBUG) {
    Firebase.database.useEmulator("10.0.2.2", 9000)
    Firebase.auth.useEmulator("10.0.2.2", 9099)
    Firebase.storage.useEmulator("10.0.2.2", 9199)
}

Si quieres conectar la app al nuevo proyecto real de Firebase y sus recursos reales de Firebase, puedes quitar este bloqueo o ejecutar la app en el modo de lanzamiento para que BuildConfig.DEBUG sea false.