Codelab de Firebase para Android: compila un chat amigable

1. Descripción general

captura de pantalla

Imagen: App de Chat amigable para trabajar.

Te damos la bienvenida al codelab de Friendly Chat. En este codelab, aprenderás a usar la plataforma de 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, sigue estas instrucciones. Para verificar 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

Importa 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 el proyecto build-android-start abierto en Android Studio. Si ves una advertencia sobre un archivo google-services.json que falta, no te preocupes. Se agregará en un paso posterior.

Cómo verificar 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, deberás 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 binario independiente o 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 cuando creaste tu proyecto de Firebase antes.

4. Cómo conectarse 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 de 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 inicio

Agrega google-services.json

Para que tu app para Android se conecte a Firebase, debes agregar un archivo google-services.json dentro de 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 de Firebase y una app para Android de Firebase reales para que puedas reemplazar este archivo JSON simulado por 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, está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 no podrás enviar ni recibir mensajes. En el siguiente paso de este codelab, autenticarás a los usuarios para que puedan usar el chat amigable.

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 código básico de Firebase Authentication a la app para detectar usuarios y, luego, implementaremos 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 haya 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 a los usuarios de forma correcta.

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 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 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 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 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 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, 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 de tu copia local del repositorio del codelab al visor de datos.

Ahora deberías tener algunos mensajes debajo del nodo messages de la base de datos.

Lee datos

Cómo sincronizar mensajes

En esta sección, agregaremos código que sincronice 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 en los datos.
  • Se actualizó el adaptador RecyclerView para que se muestren los 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, luego, detecta nuevas entradas secundarias en la ruta de acceso messages de tu base de datos de Firebase Realtime. 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 implementamos 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, vuelve 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 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 mensajes nuevos 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 está 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 con imágenes, sigue estos pasos:

  • Seleccionar imagen
  • Cómo controlar la selección de imágenes
  • Escribe un mensaje de imagen temporal en Realtime Database
  • Comienza a subir la imagen seleccionada
  • Actualiza 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 un 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 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)
                    })
}

Sube una imagen y actualiza 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 mensaje nuevo debería aparecer 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, intenta 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 de Firebase real y sobre todo cuando comiences a compilar una app real, te recomendamos que uses 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 cualquier nombre que desees.
  4. No necesitas Google Analytics para este codelab, por lo que puedes omitir habilitarlo en tu proyecto.
  5. Haz clic en Crear proyecto. Cuando tu proyecto esté listo, haz clic en Continuar.

Actualiza tu plan de precios de Firebase

Para usar Cloud Storage para Firebase, tu proyecto de Firebase debe tener el plan de precios de pago por uso (Blaze), lo que significa que está vinculado a una cuenta de Facturación de Cloud.

  • Una cuenta de Facturación de Cloud requiere una forma de pago, como una tarjeta de crédito.
  • Si es la primera vez que usas Firebase y Google Cloud, verifica si cumples con los requisitos para obtener un crédito de USD 300 y una cuenta de Facturación de Cloud de prueba gratuita.
  • Si realizas este codelab como parte de un evento, pregúntale al organizador si hay créditos de Cloud disponibles.

Para actualizar tu proyecto al plan Blaze, sigue estos pasos:

  1. En Firebase console, selecciona la opción para actualizar tu plan.
  2. Selecciona el plan Blaze. Sigue las instrucciones en pantalla para vincular una cuenta de Facturación de Cloud a tu proyecto.
    Si necesitabas crear una cuenta de Facturación de Cloud como parte de esta actualización, es posible que debas volver al flujo de actualización en Firebase console para completarla.

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 de tu 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 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 realicen 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 para habilitarlo (en azul) y establece 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 el panel izquierdo de Firebase console, expande Compilación y, luego, selecciona Realtime Database.
  2. Haz clic en Crear base de datos.
  3. Selecciona una ubicación para tu base de datos y, luego, haz clic en Siguiente.
    Para una app real, quieres elegir una ubicación cercana a los usuarios.
  4. Haz clic en Comenzar en modo de prueba. Lee la renuncia de responsabilidad sobre las reglas de seguridad.
    En los próximos pasos de este codelab, agregarás reglas de seguridad para proteger tus datos. No distribuyas ni expongas una app públicamente sin agregar reglas de seguridad para tu base de datos.
  5. Haz clic en Crear.
  6. Una vez que se creó la instancia de base de datos, selecciona la pestaña Reglas y actualiza la configuración de reglas con los siguientes parámetros:
     {
       "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 el panel izquierdo de Firebase console, expande Compilación y, luego, selecciona Almacenamiento.
  2. Haz clic en Comenzar.
  3. Selecciona una ubicación para el bucket de Storage predeterminado.
    Los buckets de US-WEST1, US-CENTRAL1 y US-EAST1 pueden aprovechar el nivel “Siempre gratuito” de Google Cloud Storage. Los buckets de todas las demás ubicaciones siguen los precios y el uso de Google Cloud Storage.
  4. Haz clic en Iniciar en modo de prueba. Lee la renuncia de responsabilidad sobre las reglas de seguridad.
    Más adelante en este codelab, agregarás reglas de seguridad para proteger tus datos. No distribuyas ni expongas una app de forma pública sin agregar reglas de seguridad para tu bucket de Storage.
  5. Haz clic en Crear.

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