Artigo original: How to Build a React Native App and Integrate It with Firebase

Neste tutorial, vamos construir uma aplicação em React Native integrada ao Firebase no back-end. A aplicação também terá suporte da React Native CLI e da Expo CLI.

Este tutorial de React Native com Firebase abrangerá as funcionalidades principais, como autenticação, registro e operações CRUD no banco de dados (Firestore).

Você também pode baixar o código completo no GitHub se quiser conferi-lo.

Este tutorial percorrerá os detalhes por meio das seguintes seções:

  1. Criação de um projeto com o Firebase
  2. Criação e configuração de uma aplicação em React Native
  3. Configuração da estrutura de pastas, rotas e navegação
  4. Implementação da interface para telas de login, registro e início
  5. Registro com Firebase Auth
  6. Login com Firebase Auth
  7. Persistência de credenciais de login
  8. Escrita e leitura de dados a partir do Firebase Firestore

Sem mais delongas, vamos começar a construir o projeto em React Native com Firebase. A aplicação final ficará assim:

react-native-firebase-1

1. Criação de um projeto com o Firebase

Visite Firebase.com e crie uma conta. Quando fizer login, você poderá criar um projeto no Firebase Console.

  • Crie uma conta no Firebase.com
  • Crie um projeto no Firebase Console
  • Habilite o método de autenticação com e-mail e senha em Firebase Console  ->  Authentication  ->  Sign-in method
1__J2bqHTUxhs_sTxwRdbvAg
  • Crie uma aplicação para o iOS, com o ID de aplicação com.reactnativefirebase
1_RFyy5eHgUlZIEQtaCj5ddA
  • (Opcional) Crie uma aplicação do Android com o nome de pacote com.reactnativefirebase
  • Baixe no seu computador o arquivo de configuração gerado no próximo passo (GoogleService-Info.plist para iOS e google-services.json para Android)

O Firebase permite construir aplicações sem o back-end. É um produto que executa por dentro da Google Cloud e permite que os desenvolvedores construam aplicações para a web e dispositivos móveis sem precisarem de seus próprios servidores.

Isso faz você economizar muito tempo, por não haver a necessidade de escrever código para o back-end. Também é muito escalável, sendo sustentado pela infraestrutura do Google.

No Firebase, você poderá armazenar tudo que é necessário para sua aplicação – usuários, dados, arquivos, tokens para notificações por push, etc. Toda essa informação fica disponível nos clients para dispositivos móveis a partir dos SDKs do Firebase, que são compatíveis com o React Native. Isso significa que todas as interações com o back-end ficam abstraídas e encapsuladas no SDK. Então, os desenvolvedores para dispositivos móveis não precisam se preocupar com chamadas para API, análise de dados, gerenciamento de sockets e outros aspectos.

2. Criação e configuração de uma aplicação em React Native

Vamos deixar nossa aplicação do React Native com Firebase compatível com a Expo CLI e a React Native CLI.‌‌ Vamos usar o Expo por agora, pois facilita a visualização da aplicação. Não usaremos, no entanto, bibliotecas específicas do Expo. Assim, o código fonte será usado de maneira simples em qualquer aplicação do React Native, não importando no que ele está baseado. ‌‌Vamos usar o SDK Web do Firebase, que é compatível com o Expo e com a React Native CLI, além de ter suporte direto do Google.

Se você quiser usar react-native-firebase como alternativa, fique à vontade para instalar e configurar (o código permanecerá o mesmo). Saiba que não recomendamos isso por alguns motivos:

  • ele não possui suporte direto do Google, o que torna a manutenção mais difícil, dado que é uma camada extra que pode causar bugs e
  • ele não funciona com o Expo, o que pode ser um problema para muitos desenvolvedores.

Os passos a seguir também estão na documentação oficial do React Native, em Como configurar seu ambiente de desenvolvimento (em inglês).

  • Instale a Expo CLI

No seu terminal, execute

npm install -g expo-cli

  • Crie uma aplicação do React Native executando

expo init react-native-firebase

Para o template, escolha Managed Workflow — Blank

  • Inicie a aplicação executando
yarn ios
// ou
yarn android

O comando também fornecerá a você um QR Code que pode ser escaneado usando a aplicação de Camera, no iOS, ou o Expo, no Android.

Ótimo. Agora temos uma nova aplicação do React Native, executando no iOS e no Android. Vamos começar conectando-a ao nosso back-end usando o Firebase.

  • Adicione o SDK do Firebase no projeto React Native

yarn add firebase

  • Adicione a biblioteca React Native Navigation executando
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
  • Adicione vários componentes à interface e pacotes que serão usados no projeto

yarn add react-native-keyboard-aware-scroll-view base-64

Crie um arquivo de configuração para o Firebase

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

Adicione a configuração do seu firebase em src/firebase/config.js:

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

const firebaseConfig = {
  apiKey: 'YOUR_KEY_HERE_AIzaSyAOWH',
  authDomain: 'your-auth-domain-b1234.firebaseapp.com',
  databaseURL: 'https://your-database-name.firebaseio.com',
  projectId: 'your-project-id-1234',
  storageBucket: 'your-project-id-1234.appspot.com',
  messagingSenderId: '12345-insert-yourse',
  appId: 'insert yours: 1:1234:web:ee873bd1234c0deb7eba61ce',
};

if (!firebase.apps.length) {
    firebase.initializeApp(firebaseConfig);
}

export { firebase };

Você consegue toda a informação a partir do Firebase Console  -> Project Settings

1_RU6D6YeIhpIprROu8lmOOw

3. Configuração da estrutura de pastas, rotas e navegação

  • Crie a estrutura da pasta executando
mkdir src/screens src/screens/LoginScreen src/screens/RegistrationScreen src/screens/HomeScreen
  • Crie a estrutura de arquivos executando
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
  • Adicione 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'

Não se preocupe se o projeto apresentar erros! Tudo fará sentido daqui a pouco.

  • Configure as rotas e navegações

Sobrescreva o arquivo App.js com o seguinte código:

import 'react-native-gesture-handler';
import React, { useEffect, useState } from 'react'
import { NavigationContainer } from '@react-navigation/native'
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. Implementação da interface

Agora que temos a base da aplicação, vamos continuar e implementar os componentes para a interface de todas as telas. Não falaremos sobre layout flexível, nem sobre estilização do React Native, visto que esses pontos estão fora do escopo deste tutorial. Vamos focar na integração entre React Native e Firebase.

Sobrescreva os arquivos a seguir:

  • src/LoginScreen/LoginScreen.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 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="#aaaaaa"
                    onChangeText={(text) => setEmail(text)}
                    value={email}
                    underlineColorAndroid="transparent"
                    autoCapitalize="none"
                />
                <TextInput
                    style={styles.input}
                    placeholderTextColor="#aaaaaa"
                    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,
        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/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='Full Name'
                    placeholderTextColor="#aaaaaa"
                    onChangeText={(text) => setFullName(text)}
                    value={fullName}
                    underlineColorAndroid="transparent"
                    autoCapitalize="none"
                />
                <TextInput
                    style={styles.input}
                    placeholder='E-mail'
                    placeholderTextColor="#aaaaaa"
                    onChangeText={(text) => setEmail(text)}
                    value={email}
                    underlineColorAndroid="transparent"
                    autoCapitalize="none"
                />
                <TextInput
                    style={styles.input}
                    placeholderTextColor="#aaaaaa"
                    secureTextEntry
                    placeholder='Password'
                    onChangeText={(text) => setPassword(text)}
                    value={password}
                    underlineColorAndroid="transparent"
                    autoCapitalize="none"
                />
                <TextInput
                    style={styles.input}
                    placeholderTextColor="#aaaaaa"
                    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,
        marginLeft: 30,
        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
    }
})

Até aqui, sua aplicação deve executar corretamente e mostrar as seguintes telas (interface apenas):

1_rwQyQ3ZCE7rgHukTAeLliw

Você pode mudar entre as duas telas pressionando os links no rodapé.

Agora que temos uma interface bonita de login e registro, vamos ver como podemos integrar nossa aplicação do React Native (e Expo) com o Firebase.

5. React Native com Firebase  —  registro

Vamos começar criando uma conta com o Firebase Auth, pois o login acontece depois. Para isso, vamos adicionar a lógica do Firebase para criar uma conta com e-mail e senha em RegistrationScreen.js, implementando o método onRegisterPress, assim:

//...

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

//...

export default function RegistrationScreen({navigation}) {
    //...

    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)
        });
    }
    
    //...
}

No fluxo de criação de senha acima, fizemos algumas coisas importantes:

  • Chamamos a função createUserWithEmailAndPassword, da API do Firebase Auth (linha 13), que cria uma conta que será mostrada na tabela em Firebase Console -> Authentication.
  • Se o registro da conta foi feito com sucesso, também armazenamos os dados do usuário no Firebase Firestore (linha 24). Isso é necessário para armazenar informações adicionais do usuário, como nome completo, URL da foto de perfil e assim por diante, que não podem ser armazenadas na tabela de autenticação.
  • Se o registro foi feito com sucesso, vamos navegar para a tela de início, também passando os dados do usuário como objeto.
  • Se qualquer erro ocorrer, simplesmente mostramos um alerta mostrando o erro. Erros podem acontecer por causa de conexão de rede, senha muito curta, e-mail inválido e assim por diante.

Recarregue sua aplicação e teste o registro. Se você criou uma conta com sucesso, veja se ela aparece em Firebase Console  ->  Authentication:

1_qy_k5wsgw4MAALmIeBxYpg

6. React Native com Firebase  —  login

Agora que conseguimos criar as contas, vamos implementar a funcionalidade de login. O SDK do Firebase cuida de todos os passos necessários para que o login tenha autorização e autenticação seguras.

Abra LoginScreen.js, importe o firebase e complete o 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().collection('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)
            })
    }

    //...

}

Recarregue sua aplicação e faça login com uma conta existente. A aplicação deverá enviar você para a tela de início se as credenciais estiverem corretas, ou mostrará um alerta com um erro, se algo der errado.

7. Persistência de credenciais de login

Você verá que, se sair da aplicação e abri-la novamente, ela mostrará a tela de login de novo. Para uma boa experiência do usuário, queremos redirecionar todos os usuários para a tela de início. Ninguém quer digitar suas credenciais de login toda vez que quiser usar a aplicação.

Isso também é conhecido como persistência de login. Felizmente, o SDK do Firebase cuida disso para nós, lidando com todas as questões de segurança. A persistência de login está habilitada por padrão no Firebase. Então, tudo que precisamos fazer é buscar pelo usuário atual que fez login.

Abra o arquivo App.js e vamos implementar a funcionalidade de persistência de login:

//...

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 retorna o usuário atual que fez login. Então, procuramos toda a informação adicional que armazenamos no Firebase e a indicamos no estado atual do componente. Isso renderizará a aplicação novamente, o que mostrará a tela de início.

Note que, como usamos a função pela primeira vez, a aplicação carregou utilizando o hook useEffect.

8. Escrita e leitura de dados a partir do Firebase Firestore

Já usamos o Firebase acima, para salvar informações adicionais sobre nossos usuários (o nome completo). Nesta seção, vamos ver como podemos escrever dados no Firebase e como podemos buscá-los.

Vamos compreender como observar (ouvir) mudanças na coleção do Firebase e refleti-las na tela, em tempo real. Isso pode ser muito útil em aplicações de tempo real, como o React Native Chat.

Para simplificar, vamos salvar alguns itens textuais na coleção do Firestore chamada "entities" (entidades). Pense nesses itens como se fossem tarefas, postagens, tweets, qualquer coisa. Vamos criar um arquivo simples, que adiciona uma nova entidade, e vamos também listar todas as entidades que pertencem ao usuário atual que fez login. Além disso, a lista será atualizada em tempo real.

  • Implemente HomeScreen.js reescrevendo-o com o código abaixo
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("authorID", "==", 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="#aaaaaa"
                    onChangeText={(text) => setEntityText(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>
    )
}
  • Estilize a tela inicial, sobrescrevendo HomeScreen/styles.js com:
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: '#cccccc',
        borderBottomWidth: 1,
        paddingBottom: 16
    },
    entityText: {
        fontSize: 20,
        color: '#333333'
    }
})
  • Recarregue a aplicação e observe a nova tela inicial. Digite algo e pressione o botão Add.
  • Nada acontece.
  • Crie um índice nas entidades da coleção do Firestore

Você verá que a lista de entidades não foi renderizada. Se conferirmos os registros, veremos um aviso sobre "a busca precisar de um índice", seguido de um grande URL:

1_bfOrtReOOo9B_pDR4_Zm9w

Isso nos informa que não podemos buscar tabelas de entidades pelo authorID e classificar os dados por createdAt em ordem decrescente, a menos que criemos um índice. Criar um índice é bem fácil, na verdade—simplesmente clique no URL e, então, clique no botão:

1_72kARyPWnDypbCko7e4U1Q
  • Recarregue a aplicação novamente

Agora, tudo funciona como o esperado:

  • A aplicação lista todas as entidades na coleção entities, em ordem decrescente de acordo com a criação
  • Adicionar uma nova entidade funciona
  • A lista atualiza em tempo real (tente apagar um registro diretamente do banco de dados ou adicionar um novo diretamente da aplicação)

Seu banco de dados do Firestore, agora, fica assim:

1_zPT7lLNr6kvtdazgN50eKg

É assim que você lê e escreve no Firestore em React Native. Vamos para a última seção.

Brinque com a aplicação, adicionando novas entidades. Este é o projeto final:

react-native-firebase-2

Conclusão

O Firebase facilita o suporte para autenticação e banco de dados para qualquer aplicação em React Native. O SDK do Firebase é extremamente poderoso, suporta vários padrões de leitura e escrita em bancos de dados.

Além do React Native, o SDK do Firebase providencia suporte para várias outras linguagens, como Swift,  Kotlin ou Flutter. Confira esses links para ver instruções para os iniciantes no Firebase em várias linguagens.

Mostramos o básico neste tutorial de React Native com Firebase. Nos próximos, vamos abranger mais funcionalidades avançadas, como Firebase Storage (carregamento de arquivos) e notificações por push.

Se você gostou deste tutorial, dê uma estrela no repositório do GitHub e compartilhe este artigo com sua comunidade. Você pode conferir muitos projetos gratuitos em React Native no Instamobile. Abraços!