Codelab de Firebase para Android: Crea un chat amigable

1. Descripción general

captura de pantalla

Imagen: App de Chat amigable para trabajar.

Te damos la bienvenida al codelab del chat amigable. 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 que los usuarios accedan.
  • 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 a fin de desarrollar una app para Android con Firebase.

Requisitos

  • La versión más reciente de Android Studio
  • Un emulador de Android con Android 5.0 o una versión posterior
  • Node.js versión 10 o posterior (para usar Emulator Suite).
  • Java 8 o superior. Para instalar Java, usa estas instrucciones. Para comprobar tu versión, ejecuta java -version.
  • Estar familiarizado con 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) en el directorio en el que descargaste el código de muestra.

Ahora deberías tener abierto el proyecto build-android-start en Android Studio. Si aparece 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 para instalarlo a través de npm.

Una vez que hayas instalado la CLI, la ejecución de 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 nueva ventana del navegador para completar el proceso de acceso. Asegúrate de elegir la misma cuenta que usaste antes cuando creaste el proyecto de Firebase.

4. Conéctate a Firebase Emulator Suite

Inicia 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.

Navega 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 en ejecución durante el resto del codelab.

Conecta tu app

En Android Studio, abre MainActivity.kt y, luego, 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

Para que tu app para Android se conecte con Firebase, debes agregar un archivo google-services.json en la carpeta app de tu proyecto de Android. A los fines de este codelab, proporcionamos un archivo JSON ficticio 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 de Firebase y una app de Firebase para Android, de modo que puedas reemplazar este archivo JSON ficticio 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, estarás listo para 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, y enviar y recibir mensajes no funcionará. 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 funcionalidad de acceso básica

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

Verificar el 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 que binding se adjunte 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 Salir:

MainActivity.kt

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

Ahora tenemos toda la lógica 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 usa 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 Auth en la clase SignInActivity en el 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 a 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 de 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 unas pocas llamadas de método y sin necesidad de administrar ninguna configuración del servidor.

Prueba tu trabajo

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

Después de acceder, abre la IU de Firebase Emulator Suite en el navegador y, luego, 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.

Importar 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 desde 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

Cómo 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:

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

MainActivity.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 busca entradas secundarias nuevas 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 necesitamos mostrar mensajes que sean imágenes, por lo que también debes 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, en 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, luego, 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 capacidad para que los usuarios de apps 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 del objeto enviado. Estos IDs son secuenciales, lo que garantiza que los nuevos mensajes se agregarán 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 de imagen

En esta sección, agregarás la capacidad para que los usuarios de apps 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 utiliza 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 se implementa en el código al final del método onCreate(). Cuando termina, llama al método onImageSelected() de MainActivity. Con el siguiente fragmento de código, escribirás un mensaje con una URL de imagen temporal en 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 el mensaje

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

MainActivity.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 presiona el botón de enviar. El mensaje nuevo debería estar visible 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 nuevo mensaje debería ser visible primero con una imagen de marcador de posición y, luego, con la imagen seleccionada una vez que se complete la carga. El mensaje nuevo 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 Storage.

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, prueba usar 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 próximo 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 que usarás en este codelab. También agregarás la configuración de Firebase específica de tu app. Por último, configurarás recursos reales de Firebase que usarás con tu app.

Crea un proyecto de Firebase

  1. En tu navegador, ve a Firebase console.
  2. Selecciona Agregar proyecto.
  3. Selecciona o ingresa un nombre de proyecto. Puedes usar el nombre que quieras.
  4. No necesitas Google Analytics para realizar este codelab, 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 el proyecto de Android con el de Firebase:

  1. En la pantalla de descripción general del nuevo proyecto, 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 de 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 siguientes pasos que se muestran en el flujo de trabajo de configuración de la consola (ya se realizaron automáticamente en el proyecto build-android-start).
  6. Asegúrate de que todas las dependencias estén disponibles para tu app sincronizando tu proyecto con archivos Gradle. Desde 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 quieras usar en tu app.

  1. En Firebase console, selecciona Authentication en el panel de navegación izquierdo.
  2. Selecciona la pestaña Método de acceso.
  3. Haz clic en Correo electrónico/contraseña y, a continuación, activa el interruptor (azul).
  4. Haz clic en Google, activa el interruptor (azul) y configura un correo electrónico de asistencia del proyecto.

Si más adelante en este codelab aparecen 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 izquierdo.
  2. Haz clic en Crear base de datos para crear una nueva instancia de Realtime Database. Cuando se te solicite, selecciona la región us-central1 y, luego, haz clic en Siguiente.
  3. Cuando se te pregunten las reglas de seguridad, elige modo bloqueado y, luego, haz clic en Habilitar.
  4. Cuando se haya creado la instancia de base de datos, selecciona la pestaña Reglas y, luego, actualiza la configuración de las 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 de 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.

Cómo conectarse 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 tu app al nuevo proyecto real de Firebase y sus recursos reales de Firebase, puedes quitar este bloqueo o ejecutar la app en modo de lanzamiento para que BuildConfig.DEBUG sea false.