Original article: How to Build a React Native App and Integrate It with Firebase

En este tutorial, vamos a construir una aplicación React Native que está integrado con un backend de Firebase. La aplicación soportará tanto el CLI de React Native como el CLI de Expo.

Este tutorial de React Native Firebase cubrirá las características principales como autenticación, registro, y operaciones CRUD de bases de datos (Firestore).

Puedes también descargar todo el código abierto desde Github si quieres saltar directo al código.

Este tutorial te llevará a través de los detalles de las siguientes secciones:

  1. Crear un proyecto de Firebase
  2. Crear & configurar una nueva aplicación React Native
  3. Configurar la estructura de carpeta, rutas, y navegación
  4. Implementar la UI para el Login, el Registro, y las ventanas de Inicio
  5. Registro con Firebase Auth
  6. Inicio de Sesión con Firebase Auth
  7. Credenciales de Inicio de Sesión Persistentes
  8. Escribir y leer datos desde Firebase Firestore

Sin más, comencemos a construir el proyecto de React Native Firebase. La aplicación móvil final se verá así:

react native firebase

1. Crear un proyecto de Firebase

Ver a Firebase.com y crea una nueva cuenta. Una vez que inicies sesión, serás capaz de crear un nuevo proyecto en la Consola de Firebase.

  • Crear una nueva cuenta en Firebase.com
  • Crear un nuevo proyecto en la Consola de Firebase
  • Permitir método de autenticación con Email & Contraseña en Firebase Console -> Authentication -> Sign-in method
1__J2bqHTUxhs_sTxwRdbvAg
  • Crear una nueva aplicación iOS, con el ID App com.reactnativefirebase
1_RFyy5eHgUlZIEQtaCj5ddA
  • (Opcional) Crear una nueva aplicación Android con el nombre de paquete com.reactnativefirebase
  • Descargar el archivo de configuración generado en el siguiente paso a tu computadora (GoogleService-Info.plist para iOS, y google-services.json para Android)

Firebase te permite construir aplicaciones sin backend. Es un producto que corre sobre la Nube de Google, y permite a los desarrolladores construir aplicaciones web y móviles sin necesidad de tener sus propios servidores.

Esto ahorra mucho tiempo, ya que no necesitas escribir ningún código de backend. Es altamente escalable también, siendo soportado por la infraestructura de Google.

En Firebase, serás capaz de almacenar todo lo que es necesario para tu aplicación – usuarios, datos, archivos, enviar tokens de notificación, etc. Toda esta información se hace disponible a los clientes móviles via los SDKs de Firebase, lo cuales son compatibles con React Native. Esto significa que todas las interacciones con el backend son abstraídos y encapsulados en el SDK, así los desarrolladores móviles se preocupen sobre llamadas API, conversiones de datos, gestión de sockets, y así sucesivamente.

2. Crear y configurar una nueva aplicación React Native

Vamos a hacer nuestra aplicación React Native con Firebase compatible tanto con el CLI de Expo como con el CLI de React Native.

Vamos a usar Expo por ahora, ya que lo hace fácil a los principiantes para previsualizar sus aplicaciones. Pero no usaremos ninguna librería específica de Expo, así que el código de src puedes ser simplemente usado en cualquier aplicación de React Native, sin importar de su estructura.

Vamos a usar el SDK Web de Firebase, el cual es compatible con Expo y con el CLI de React Native, y es soportado directamente por Google.

Si quieres usar react-native-firebase, siéntete libre de instalarlo y configurarlo (el código aún será el mismo). Pero ten en mente que no lo recomiendo por unas pocas razones:

  • no está soportado directamente por Google, así que mantenerlo serás más duro dado que es una capa extra que puede causar errores, y
  • tampoco funciona con Expo, lo que puedes ser un factor decisivo para muchos desarrolladores.

Los pasos abajo están también cubiertos en la documentación oficial de React Native en como configurar tu entorno de desarrollo.

  • Instalar el CLI de Expo

En tu Terminal, simplemente ejecuta

npm install -g expo-cli
  • Crea una nueva aplicación React Native ejecutando
expo init react-native-firebase

Para la plantilla, elige el Managed Workflow — Blank

  • Comienza la aplicación ejecutando
yarn ios
// or
yarn android

Esto también te presentará con un código QR el cual puedes escanear usando la aplicación Cámara en iOS, o la aplicación Expo en Android.

Esto es genial. Ahora tenemos una nueva aplicación React Native, ejecutándose tanto en iOS como en Adroid. Empecemos conectándolo a tu backend de Firebase.

  • Agregar el SDK de Firebase al proyecto de React Native
yarn add firebase
  • Agregar la librería de Navegación de React Native Navigation ejecutando
yarn add @react-navigation/native && yarn add @react-navigation/stack && expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
  • Agregar varios componentes UI y paquetes a ser usados en el proyecto
yarn add react-native-keyboard-aware-scroll-view base-64

Crear un archivo de configuración de Firebase

mkdir src src/firebase && touch src/firebase/config.js

Agregar tu configuración de Firebase en src/firebase/config.js:

import * as firebase from 'firebase';
import '@firebase/auth';
import '@firebase/firestore';

const configuracionFirebase = {
  claveAPI: 'TU_CLAVE_AQUI_AIzasyAOWH',
  dominioAuth: 'tu-dominio-auth-b1234.firebaseapp.com',
  urlBaseDeDatos: 'https://tu-nombre-basededatos-firebaseio.com',
  idProyecto: 'tu-id-proyecto-1234',
  presupuestoAlmacenamiento: 'tu-id-proyecto-1234.appspot.com',
  idRemitenteMensajes: '12345-insertar-tuyo',
  idApp: 'inserta el tuyo: 1:1234:web:ee873bdu1234codeb7eba61ce',
 }
 
 if (!firebase.apps.length) {
 	firebase.initializeApp(configuracionFirebase);
 }
 
 export {firebase};

Puedes obtener toda esta información desde Firebase Console -> Project Settings

1_RU6D6YeIhpIprROu8lmOOw

3. Crear la estructura de carpeta y configurar las rutas y la navegación

  • Crea la estructura de carpeta ejecutando
mkdir src/screens src/screens/LoginScreen src/screens/RegistrationScreen src/screens/HomeScreen
  • Crea la estructura de archivos ejecutando
touch src/screens/index.js src/screens/LoginScreen/LoginScreen.js src/screens/LoginScreen/styles.js src/screens/RegistrationScreen/RegistrationScreen.js src/screens/styles.js src/screens/HomeScreen/HomeScreen.js src/screens/HomeScreen/styles.js
  • Agrega este código a src/screens/index.js
export { default as LoginScreen } from './LoginScreen/LoginScreen'

export { default as HomeScreen } from './HomeScreen/HomeScreen'

export { default as RegistrationScreen } from './RegistrationScreen/RegistrationScreen'

¡No te preocupes si el proyecto está roto! Todo tendrá sentido en un ratito.

  • Configurar las rutas & navegadores

Sobreescribe el archivo App.js con el siguiente fragmento de código:

import 'react-native-gesture-handler';
import React, { useEffect, useState } from 'react';
import { NavigationContainer } from '@react-navigation/natie';
import { createStackNavigator } from '@react-navigation/stack';
import { LoginScreen, HomeScreen, RegistrationScreen } from './src/screens';
import { decode, encode } from 'base-64';

if (!global.btoa) { global.btoa = encode }
if (!global.atob) { global.atob = decode }

const Stack = createStackNavigator();

export default function App() {
  const [loading, setLoading] = useState(true);
  const [user, setUser] = useState(null);
  
  return (
    <NavigationContainer>
      <Stack.Navigator>
        {  user? (
          <Stack.Screen name="Home">
            {props => <Homescreen {...props} extraData={user} />}
          </Stack.Screen>
          ) : (
            <>
              <Stack.Screen name="Login" component={LoginScreen} />
              <Stack.Screen name="Registration" component={RegistrationScreen} />
            </>
          )}
      </Stack.Navigator>
    </NavigationContainer>
  );
}

4. Implementar la UI

Ahora que tenemos la estructura de la aplicación, vamos a continuar hacia adelante e implementemos los componentes UI de todas las pantallas. No vamos a ir en detalle sobre el diseño flex y el diseño de React Native, ya que está fuera del enfoque para este tutorial. Vamos a enfocarnos mayormente en la integración de React Native con Firebase.

Simplemente sobreescribe los archivos como sigue:

  • src/LoginScreen/LoginScreen.js
import React, { useState } from 'react'
import { Image, Text, TextInput, TouchableOpacity, View } from 'react-native'
import { KeyboardAdwareScrollView } from 'react-native-keyboard-aware-scroll-view'
import styles from './styles'

export default function LoginScreen({ navigation }) {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  
  const onFooterLinkPress = () => {
    navigation.navigate('Registration')
  }
  
  const onLoginPress = () => {
  }
  
  return (
    <View style={styles.container}>
      <KeyboardAwareScrollView
        style={{ flex: 1, width: '100%' }}
        keyboardShouldPersistTaps="always">
        <Image
          style={styles.logo}
          source={require('../../../assets/icon.png')}
        />
        <TextInput
          style={styles.input}
          placeholder="E-mail"
          placeholderTextColor="#aaa"
          onChangeText={(text) => setEmail(text)}
          value={email}
          underlineColorAndroid="transparent"
          autoCapitalize="none"
        />
        <TextInput
          style={styles.input}
          placeholderTextColor="#aaa"
          secureTextEntry
          placeholder="Password"
          onChangeText={(text) => setPassword(text)}
          value={password}
          underlineColorAndroid="transparent"
          autoCapitalize="none"
        />
        <TouchableOpacity
          style={styles.button}
          onPress={() => onLoginPress()}>
          <Text style={styles.buttonTitle}>Log in</Text>
        </TouchableOpacity>
        <View style={styles.footerView}>
          <Text style={styles.footerText}>Don't have an account? <Text onPress={onFooterLinkPress} style={styles.footerLink}>Sign up</Text></Text>
        </View>
      </KeyboardAwareScrollView>
    </View>
  )
}
  • src/LoginScreen/styles.js
import { StyleSheet } from 'react-native'

export default StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center'
  },
  title: {
  
  },
  logo: {
    flex: 1,
    height: 120,
    width: 90,
    alignSelf: "center",
    margin: 30
  },
  input: {
    height: 48,
    borderRadius: 5,
    overflow: 'hidden',
    backgroundColor: 'white',
    marginTop: 10,
    marginBottom: 10,
    marginLeft: 30,
    paddingLeft: 16
  },
  button: {
    backgroundColor: '#788eec',
    marginLeft: 30,
    marginRight: 30,
    marginTop: 20,
    height: 48,
    borderRadius: 5,
    alignItems: 'center',
    justifyContent: 'center'
  },
  buttonTitle: {
    color: 'white',
    fontSize: 16,
    fontWeight: 'bold'
  },
  footerView: {
    flex: 1,
    alignItems: 'center',
    marginTop: 20
  },
  footerText: {
    fontSize: 16,
    color: '#2e2e2d'
  },
  footerLink: {
    color: '#788eec',
    fontWeight: 'bold',
    fontSize: 16
})
  • src/RegistrationScreen/RegistrationScreen.js
import React, { useState } from 'react'
import { Image, Text, TextInput, TouchableOpacity, View } from 'react-native'
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import styles from './styles';

export default function RegistrationScreen({ navigation }) {
  const [fullName, setFullName] = useState('')
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [confirmPassword, setConfirmPassword] = useState('')
  
  const onFooterLinkPress = () => {
    navigation.navigate('Login')
  }
  
  const onRegisterPress = () => {
  
  }
  
  return (
    <View style={styles.container}>
      <KeyboardAwareScrollView
        style={{ flex: 1, width: '100%' }}
        keyboardShouldPersistTaps="always">
        <Image
          style={styles.logo}
          source={require('../../../assets/icon.png')}
        />
        <TextInput
          style={styles.input}
          placeholder="Fullname"
          placeholderTextColor="#aaa"
          onChangeText={(text) => setFullName(text)}
          value={fullName}
          underlineColorAndroid="transparent"
          autoCapitalize="none"
        />
        <TextInput
          style={styles.input}
          placeholder="Email"
          placeholderTextColor="#aaa"
          onChangeText={(text) => setEmail(text)}
          value={email}
          underlineColorAndroid="transparent"
          autoCapitalize="none"
        />
        <TextInput
          style={styles.input}
          placeholderTextColor="#aaa"
          secureTextEntry
          placeholder="Password"
          onChangeText={(text) => setPassword(text)}
          value={password}
          underlineColorAndroid="transparent"
          autoCapitalize="none"
        />
        <TextInput
          style={styles.input}
          placeholderTextColor="#aaa"
          secureTextEntry
          placeholder="Confirm Password"
          onChangeText={(text) => setConfirmPassword(text)}
          value={confirmPassword}
          underlineColorAndroid="transparent"
          autoCapitalize="none"
        />
        <TouchableOpacity
          style={styles.button}
          onPress={() => onRegisterPress()}>
          <Text style={styles.buttonTitle}>Create account</Text>
        </TouchableOpacity>
        <View style={styles.footerView}>
          <Text style={styles.footerText}>Already got an account? <Text onPress={onFooterLinkPress} style={styles.footerLink}>Log in</Text></Text>
        </View>
      </KeyboardAwareScrollView>
    </View>
  )
}
  • src/RegistrationScreen/styles.js
import { StyleSheet } from 'react-native'

export default StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center'
  },
  title: {
  
  },
  logo: {
    flex: 1,
    height: 120,
    width: 90,
    alignSelf: 'center',
    margin: 30
  },
  input: {
    height: 48,
    borderRadius: 5,
    overflow: 'hidden',
    backgroundColor: 'white',
    marginTop: 10,
    marginBottom: 10,
    marginRight: 30,
    paddingLeft: 16
  },
  button: {
    backgroundColor: '#788eec',
    marginLeft: 30,
    marginRight: 30,
    marginTop: 20,
    height: 48,
    borderRadius: 5,
    alignItems: 'center',
    justifyContent: 'center',
  },
  buttonTitle: {
    color: 'white',
    fontSize: 16,
    fontWeight: 'bold'
  },
  footerView: {
    flex: 1,
    alignItems: 'center',
    marginTop: 20
  },
  footerText: {
    fontSize: 16,
    color: '#2e2e2d'
  },
  footerLink: {
    color: '#788eec',
    fontWeight: 'bold',
    fontSize: 16
  }
})
  • src/HomeScreen/HomeScreen.js
import React from 'React'
import { Text, View } from 'react-native'

export default function HomeScreen(props) {
  return (
    <View>
      <Text>Home Screen</Text>
    </View>
  )
}
  • src/HomeScreen/styles.js
import { StyleSheet } from 'react-native'

export default StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center'
  },
  input: {
    height: 48,
    borderRadius: 5,
    overflow: 'hidden',
    backgroundColor: 'white',
    marginTop: 10,
    marginBottom: 10,
    marginLeft: 30,
    marginRight: 30,
    paddingLeft: 16
  }
})

A este punto, tu aplicación debería ejecutarse apropiadamente y mostrar las siguientes pantallas (UI solamente):

react native firebase auth

Puedes cambiar entre las dos pantallas tocando los botones de enlaces en el pie de página.

Ahora que tenemos una UI hermosa para iniciar sesión y registrarse, veamos cómo podemos integrar nuestra aplicación React Native (y Expo) con Firebase.

5. React Native con Firebase — Registro

Empecemos con crear una nueva cuenta con Firebase Auth, ya que naturalmente el inicio de sesión viene después. Para esto, vamos a agregar la lógica de Firebase para crear una nueva cuenta con email & contraseña en el RegistrationScreen.js, implementando el método onRegisterPress como sigue:

// ... El mismo código de antes continúa y agregamos 
import { firebase } from "../../firebase/config"
// ...

export default function RegistrationScreen({ navigation }) {
  // ... El mismo código de antes continúa y agregamos
  const onRegisterPress = () => {
    if (password !== confirmPassword) {
      alert("Passwords don't match."),
      return
    }
    firebase
      .auth()
      .createUserWithEmailAndPassword(email, password)
      .then((response) => {
        const uid = response.user.uid
        const data = {
          id: uid,
          email,
          fullName
        },
        const usersRef = firebase.firestore().collection('users')
        usersRef
          .doc(uid)
          .set(data)
          .then(() => {
            navigation.navigate('Home', { user: data })
          })
          .catch((error) => {
            alert(error)
          })
        })
        .catch((error) => {
          alert(error)
        }
      })
    }
    // ...
}

En el flujo de creación de cuenta de arriba, hacemos un par de cosas importantes:

  • Llamamos a la API createUserWithEmailAndPassword de Auth de Firebase (línea 13), el cual crea una nueva cuenta que se mostrará en Firebase Console -> Authentication table.
  • Si el registro de la cuenta fue exitosa, también almacenamos los datos del usuario en el Firestore  de Firebase (línea 24). Esto es necesario para almacenar información extra del usuario, tal como el nombre completo, URL de la foto de perfil, y así sucesivamente, el cual no puede ser almacenado en la tabla de Autenticación.
  • Si el registro fue exitoso, navegamos al Home Screen, pasando los datos del objeto del usuario también.
  • Si algún error ocurre, simplemente lo mostramos en una alerta. Los errores pueden ser cosas como conexión de red, contraseñas demasiadas cortas, email inválido, y así sucesivamente.

Recarga tu aplicación y prueba el registro. Si creó una cuenta exitosamente, verifícalo si se muestra en Firebase Console -> Authentication:

1_qy_k5wsgw4MAALmIeBxYpg

6. React Native con Firebase — Inicio de sesión

Ahora que somos capaz de crear nuevas cuentas, implementemos la funcionalidad de iniciar sesión. El SDK de Firebase se encarga de todos los pasos de autorización y autenticación para un inicio de sesión seguro.

Abre LoginScreen.js, importa Firebase y completa el método onLoginPress:

...
import { firebase } from '../../firebase/config'
...

export default function LoginScreen({ navigation }) {
  ...
  const onLoginPress = () => {
    firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then((response) => {
        const uid = response.user.uid
        const usersRef = firebase.firestore().colecction('users')
        usersRef
          .doc(uid)
          .get()
          .then(firestoreDocument => {
            if (!firestoreDocument.exists) {
              alert("User does not exist anymore".)
              return;
            }
            const user = firestoreDocument.data()
            navigation.navigate('Home', {user})
          })
          .catch(error => {
            alert(error)
          })
        })
      .catch(error => {
        alert(error)
      })
  }
  ...
}

Recarga tu aplicación y ve hacia adelante e inicia sesión con una cuenta existente. La aplicación debería llevarte a la pantalla de inicio si las credenciales eran correctas, o te alertará con un error si algo anduvo mal.

7. Persistir las credenciales de inicio de sesión

Notarás que si quitas las aplicación y lo abres nuevamente, te mostrará la pantalla de inicio de sesión otra vez. Para una buena experiencia de usuario, nos gustaría que lleguen todos los usuarios que iniciarion sesión en la pantalla de Inicio. Nadie quiere escribir sus credenciales de inicio de sesión cada vez que quiera usar la aplicación.

Esto se conoce también com inicio de sesión persistente. Afortunadamente, el SDK de Firebase se encarga de esto por nosotros, con todas las preocupaciones de seguridad. El inicio de sesión persistente está activado por defecto en Firebase, así que todo lo que necesitamos es buscar al usuario que inicio sesión actualmente.

Abre el App.js e implementemos la característica de inicio de sesión persistente:

...
import { firebase } from './src/firebase/config'
...

export default function App() {
  ...
  if (loading) {
    return (
      <></>
    )
  }
  
  useEffect(() => {
    const usersRef = firebase.firestore().collection('users)
    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        usersRef
          .doc(user.uid)
          .get()
          .then((document) => {
            const userData = document.data()
            setLoading(false)
            setUser(userData)
          })
          .catch((error) => {
            setLoading(false)
          })
      else {
        setLoading(false)
      }
    })
  }, [])
  ...
}

onAuthStateChanged regresa el usuario que inició sesión recientemente. Después buscamos todos los datos extra del usuario que almacenamos en Firestore, y lo ponemos en el estado del componente actual. Esto re-rendizará el componente app, el cual mostrará la pantalla de Inicio.

Nota cómo lo llamamos la primera vez que carga la aplicación al aprovechar el hook useEffect.

8. Escribir y leer datos del Firestore de Firebase

Ya hemos usado Firestore arriba, para guardar información extra de nuestros usuarios (el nombre completo). En esta sección dedicada, vamos a ver cómo podemos escribir los datos a Firestore, y cómo podemos consultarla.

También cubriremos cómo observar (escuchar) los cambios en la colección de Firestore y que se reflejen en la pantalla, en tiempo real. Estos pueden ser muy útiles en aplicaciones de tiempo real, tal como React Native Chat.

Para simplificar, vamos a guardar algunos items de texto en una colección de Firestore llamado "entidades". Considéralos como tareas, posts, tweets, lo que gustes. Crearemos una archivo simple que agrega una nueva entidad y también listaremos todas las entidades que pertenecen al usuario que inició sesión recientemente. Además, la lista será actualizada en tiempo real.

  • Implementar HomeScreen.js reescribiéndolo al código de abajo
import React, { useEffect, useState } from 'react'
import { FlatList, Keyboard, Text, TextInput, TouchableOpacity, View } from 'react-native'
import styles from './styles'
import { firebase } from '../../firebase/config'

export default function HomeScreen(props) {
  const [entityText, setEntityText] = useState('')
  const [entities, setEntities] = useState([])
  
  const entityRef = firebase.firestore().collection('entities')
  const userID = props.extraData.id
  
  useEffect(() => {
    entityRef
      .where("author ID", "==", userID)
      .orderBy('createdAt', 'desc')
      .onSnapshot(
        querySnapshot => {
          const newEntities = []
          querySnapshot.forEach(doc => {
            const entity = doc.data()
            entity.id = doc.id
            newEntities.push(entity)
          })
          setEntities(newEntities)
        },
        error => {
          console.log(error)
        }
      }
    }, [])
    
    const onAddButtonPress = () => {
      if (entityText && entityText.length > 0) {
        const timestamp = firebase.firestore.FieldValue.serverTimestamp()
        const data = {
          text: entityText,
          authorID: userID,
          createdAt: timestamp,
        }
        entityRef
          .add(data)
          .then(_doc => {
            setEntityText('')
            Keyboard.dismiss()
          })
          .catch((error) => {
            alert(error)
          })
      }
    }
    
    const renderEntity = ({item, index}) => {
      return (
        <View style={styles.entityContainer}>
          <Text style={styles.entityText}>
            {index}. {item.text}
          </Text>
        </View>
      )
    }
    
    return (
      <View style={styles.container}>
        <View style={styles.formContainer}>
          <TextInput
            style={styles.input}
            placeholder="Add new entity"
            placeholderTextColor="#aaa"
            onChangeText={(text) => setEntity(text)}
            value={entityText}
            underlineColorAndroid="transparent"
            autoCapitalize="none"
          />
          <TouchableOpacity style={styles.button} onPress={onAddButtonPress}>
            <Text style={styles.buttonText}>Add</Text>
          </TouchableOpacity>
        </View>
        { entities && (
          <View style={styles.listContainer}>
            <FlatList
              data={entities}
              renderItem={renderEntity}
              keyExtractor={(item) => item.id}
              removeClippedSubviews={true}
            />
          </View>
        )}
      </View>
    )
}
  • Estilo de la pantalla inicio, sobreescribiendo HomeScreen/styles.js a:
import { StyleSheet } from 'react-native'

export default StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center'
  },
  formContainer: {
    flexDirection: 'row',
    height: 80,
    marginTop: 40,
    marginBottom: 20,
    flex: 1,
    paddingTop: 10,
    paddingBottom: 10,
    paddingLeft: 30,
    paddingRight: 30,
    justifyContent: 'center'
    alignItems: 'center'
  },
  input: {
    height: 48,
    borderRadius: 5,
    overflow: 'hidden',
    backgroundColor: 'white',
    paddingLeft: 16,
    flex: 1,
    marginRight: 5
  },
  button: {
    height: 47,
    borderRadius; 5,
    backgroundColor: '#788eec',
    width: 80,
    alignItems: 'center',
    justifyContent: 'center'
  },
  buttonText: {
    color: 'white',
    fontSize: 16
  },
  listContainer: {
    marginTop: 20,
    padding: 20
  },
  entityContainer: {
    marginTop: 16,
    borderBottomColor: '#ccc',
    borderBottomWidth: 1,
    paddingBottom: 16
  },
  entityText: {
    fontSize: 20,
    color: '#333'
  }
})
  • Recargar la aplicación y observa la nueva pantalla de inicio. Escribe algún texto y presiona el botón Agregar
  • Nada sucedió.
  • Crea un índice en la colección entidades de Firestore

Notarás que la lista de entidades no se renderiza. Si chequeas los mensajes, verás una advertencias sobre "La consulta requiere un índice", seguido de una URL larga:

1_bfOrtReOOo9B_pDR4_Zm9w

Esto nos informa que no podemos consultar la tabla de entidades por authorID y ordenar los datos por createdAt en orden descendente, a menos que creemos un índice. Crear un índice es en realidad realmente fácil – simplemente hacer click en esa URL y luego hacer click en el botón:

1_72kARyPWnDypbCko7e4U1Q
  • Recarga la aplicación nuevamente

Ahora todo funciona como se espera:

  • La aplicación lista todas las entidades en la colección de entidades, en orden de creación descendiente
  • Agregar una nueva entidad funciona bien
  • La lista se actualiza en tiempo real (intenta eliminar una entrada directamente en la base de datos, o agrega una nueva directamente desdes la aplicación)

Asi es como tu base de datos de Firestore luce ahora:

1_zPT7lLNr6kvtdazgN50eKg

Así es cómo lees y esribes desde Firestore in React Native. Movámonos a la última sección.

Juega con la aplicación, agregando nuevas entidades. Este es el proyecto final:

react-native-firebase-2

Conclusión

Firebase lo hace realmente sencillo al agregar autenticación y soporte de base de datos a cualquier aplicación React Native. El SDK de Firebase es extremadamente poderoso, soportando muchos patrones de base de datos de lectura y escritura.

Además a React Native, el SDK de Firebase provee soporte a muchísimos otros lenguajes, tales como Swift, Kotlin o Flutter. Visita esos links para kits de inicio similares en varios lenguajes.

Hemos exhibido lo más básico en tutorial de React Native Firebase. En la próxima serie, cubriremos características más avanzadas, tales como Firebase Storage (subir archivos) y mostrar notificaciones.

Si te gustó este tutorial, por favor dame una estrella en el repo de Github y compártelo con tu comunidad. Puedes chequear más proyectos gratis de React Native en Instamobile. ¡Saludos!