
React Native + FireBase(CRUD Completo) – Tasks
Passo 1
Você precisará de um conta Gmail para poder acessar o firebase e criar seu primeiro projeto.
Passo 2
Criar um banco no Firebase. Ao criar o banco devemos acessar: FireStore Database/Coud FireStore/Regras e em editar regras configurar nosso allow como true.
1 2 3 4 5 6 7 8 |
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if true; } } } |
Depois vamos em dados para criar um coleção. Vamos chamar essa coleção de Tasks e adicionar um objeto em nossa collection Tasks.
1 2 3 4 |
{ description: "estudar javascript", (sting) status: True (boolean) } |
Em visão geral do projeto podemos acessar nossas credenciais para acesso ao banco, vamos selecionar WEB e copiar nossas credenciais.
Criando nosso projeto
1 2 |
expo init tasks cd tasks |
Vamos fazer algumas instalações que iremos utilizar durante o desenvolvimento do nosso projeto.
Vamos utilizar react navigation dentro do nosso app, então rode em seu terminal dentro da pasta do projeto:
1 2 3 |
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 |
Vamos precisar também fazer a instalação do firebase no nosso projeto.
Para isso vamos rodar no terminal o seguinte comando:
1 |
yarn add firebase |
Com tudo configurado vamos agora iniciar a configuração dos arquivos dentro do nosso projeto.
Para iniciar nosso projeto vamos montar nossa estrutura de pastas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
src config firebase.js pages Task index.js style.js NewTask index.js style.js DeTails index.js style.js App.js |
Configurando nosso firebase.js dentro de src/config/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import firebase from "firebase" import 'firebase/storage'; var firebaseConfig = { apiKey: "8asd48as1das1dasd8asd1a9s8d1d81as", authDomain: "tasks-1s6a5d16a.firebaseapp.com", databaseURL: "https://tasks-1s6a5d16a-default-rtdb.com.firebaseio.com", projectId: "tasks-1s6a5d16a", storageBucket: "tasks-1s6a5d16a.appspot.com", messagingSenderId: "15561561651", appId: "1:15561561651:web:1d5a6s1d5a61d65s" }; // Initialize Firebase firebase.initializeApp(firebaseConfig); const database = firebase.firestore(); export default database |
Configurando as Rotas
Agora, vamos trabalhar dentro do nosso arquivo principal.
No App.js, abra seu arquivo, vamos editá-lo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import React from "react"; import { NavigationContainer } from "@react-navigation/native"; import { createStackNavigator } from "@react-navigation/stack"; import Task from "./src/pages/Task/"; import NewTask from "./src/pages/NewTask/"; import Details from "./src/pages/Details/"; const Stack = createStackNavigator(); export default function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Task"> <Stack.Screen name="Task" component={Task} options={{ headerTintColor: "#F92E6A", }} /> <Stack.Screen name="New Task" component={NewTask} options={{ headerTintColor: "#F92E6A", }} /> <Stack.Screen name="Details" component={Details} options={{ headerTintColor: "#F92E6A", }} /> </Stack.Navigator> </NavigationContainer> ); } |
Page Task
Construindo o index.js da Page Task:
1 – Vamos realizar os imports necessários para nossa page Task onde todas as tasks serão carregadas:
1 2 3 4 5 6 7 8 9 10 |
import React, { useState, useEffect } from "react"; import { View, Text, TouchableOpacity, FlatList, } from "react-native"; import database from "../../config/firebase.js"; import { FontAwesome } from "@expo/vector-icons"; import styles from "./style"; |
2 – Vamos criar nosso componente que irá retornar a page Task e criar a parte lógica do nosso componente, onde teremos o state task, o useEfect e a função deleteTask para deletar uma task criada:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
export default function Task({ navigation }) { const [task, setTask] = useState([]); function deleteTask(id) { database.collection("Tasks").doc(id).delete(); } useEffect(() => { database.collection("Tasks").onSnapshot((query) => { const list = []; query.forEach((doc) => { list.push({ ...doc.data(), id: doc.id }); }); setTask(list); }); }, []); |
3 – Vamos prepara nosso return onde iremos renderizar a lista de tasks que vamos trazer do Firebase:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
return ( return ( <View style={styles.container}> <FlatList showsVerticalScrollIndicator={false} data={task} renderItem={( { item } )=>{ return( <View style={styles.Tasks}> <TouchableOpacity style={styles.deleteTask} onPress={() => { deleteTask(item.id) }} > <FontAwesome name="star" size={23} color="#F92e6A" > </FontAwesome> </TouchableOpacity> <Text style={styles.DescriptionTask} onPress={()=> navigation.navigate("Details",{ id: item.id, description: item.description, }) } > {item.description} </Text> </View> ) }} /> <TouchableOpacity style style={styles.buttonNewTask} onPress={() => navigation.navigate("New Task")} > <Text style={styles.iconButton}>+</Text> </TouchableOpacity> </View> ) } |
Para finalizar, vamos adicionar algum estilo para deixar nosso app mais bonito:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import { StyleSheet } from 'react-native' const styles = StyleSheet.create({ container: { flex: 1, backgroundColor:"#fff", paddingTop: 20 }, Tasks:{ width:"100%", flexDirection:"row", justifyContent:"space-between", marginTop:5 }, deleteTask:{ justifyContent:"center", paddingLeft:15, }, DescriptionTask:{ width:"75%", alignContent:"flex-start", backgroundColor:"#f5f5f5cf", padding:12, paddingHorizontal: 20, borderRadius:50, marginBottom: 5, marginRight:15, color:"#282b2db5", }, buttonNewTask:{ width:60, height:60, position:"absolute", bottom: 30, left:20, backgroundColor:"#F92e6a", borderRadius:50, justifyContent:"center", alignItems: "center" }, iconButton:{ color:"#ffffff", fontSize:25, fontWeight:"bold", }, }); export default styles |
Page NewTask
Constuindo o index.js da Page New Task:
1- Vamos realizar os imports necessários para nossa page New Task onde iremos criar uma nova task:
1 2 3 4 |
import React, { useState } from "react"; import { View, Text, TextInput, TouchableOpacity } from "react-native"; import database from '../../config/firebase.js' import styles from "./style"; |
2 – Vamos criar nosso componente que irá retornar a page New Task e criar a parte lógica do nosso componente, onde teremos o state description e a função addTask para adicionar uma nova task:
1 2 3 4 5 6 7 8 9 10 11 |
export default function NewTask({ navigation }, props) { const [description, setDescription] = useState(null); function addTask(){ database.collection('Tasks').add({ description: description, status: false }) navigation.navigate("Task"); } |
3 – Vamos preparar nosso return onde iremos ter nosso textinput para adicionarmos uma nova task:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
return( <View style={styles.container}> <Text style={styles.label}>Description</Text> <TextInput style={styles.input} placeholder="Ex: estudar javascript" onChangeText={setDescription} value={description} /> <TouchableOpacity style={styles.buttonNewTask} onPress={()=>{ addTask() }} > <Text style={styles.iconButton}>Save</Text> </TouchableOpacity> </View> ) } |
Para finalizar, vamos adicionar algum estilo para deixar nosso app mais bonito:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
import { StyleSheet } from 'react-native' const styles = StyleSheet.create({ container: { flex:1, backgroundColor:'#fff' }, label:{ width:"90%", marginTop: 20, fontSize:16, marginLeft: 20, color:"#F92E6A" }, input:{ width:"90%", marginTop:10, padding:10, height:50, borderBottomWidth: 1, borderBottomColor:"#F92E6A", marginLeft:"auto", marginRight:"auto" }, buttonNewTask:{ width:60, height:60, position:"absolute", bottom: 30, left:20, backgroundColor:"#F92e6a", borderRadius:50, justifyContent:"center", alignItems: "center" }, iconButton:{ color:"#ffffff", fontSize:16, fontWeight:"bold", } }); export default styles |
Page Details
Constuindo o index.js da Page Details:
1- Vamos realizar os imports necessários para nossa page Details onde poderemos ver uma task e editá-la:
1 2 3 4 5 |
import React, { useState } from "react" import {View, Text, TextInput, TouchableOpacity} from "react-native" import database from "../../config/firebaseconfig" import styles from "./style" |
2 – Vamos criar nosso componente que irá retornar a page Details e criar a parte lógica do nosso componente, onde teremos o state descriptioEdit, teremos uma const idTask e a função editTask:
1 2 3 4 5 6 7 8 9 10 |
export default function Details({navigation, route}){ const [descriptionEdit, setDescriptionEdit] = useState(route.params.description) const idTask = route.params.id function editTask(description, id){ database.collection("Tasks").doc(id).update({ description: description, }) navigation.navigate("Task") } |
3 – Vamos preparar nosso return, que irá permitir a visualização e a edição da nossa task:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
return( <View style={styles.container}> <Text style={styles.label}>Description</Text> <TextInput style={styles.input} placeholder="Ex: estudar javascript" onChangeText={setDescriptionEdit} value={descriptionEdit} /> <TouchableOpacity style={styles.buttonNewTask} onPress={()=>{ editTask(descriptionEdit, idTask) }} > <Text style={styles.iconButton}>Save</Text> </TouchableOpacity> </View> ) } |
Para finalizar, vamos adicionar algum estilo para deixar nosso app mais bonito:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
import { StyleSheet } from 'react-native' const styles = StyleSheet.create({ container: { flex:1, backgroundColor:'#fff' }, label:{ width:"90%", marginTop: 20, fontSize:16, marginLeft: 20, color:"#F92E6A" }, input:{ width:"90%", marginTop:10, padding:10, height:50, borderBottomWidth: 1, borderBottomColor:"#F92E6A", marginLeft:"auto", marginRight:"auto" }, buttonNewTask:{ width:60, height:60, position:"absolute", bottom: 30, left:20, backgroundColor:"#F92e6a", borderRadius:50, justifyContent:"center", alignItems: "center" }, iconButton:{ color:"#ffffff", fontSize:16, fontWeight:"bold", } }); export default styles |
Resolvendo Warnings
Se tiver warnings ao adicionar uma nova task, siga os seguintes passos:
- Acesse node_modules / react-native / Libraries / Core / Timer / JSTimers.js
- Procure a variável MAX_TIMER_DURATION_MS
- Altere 60 * 1000 para 10000 * 1000
- Salve as alterações e reconstrua seu aplicativo.
Esse import firebase from "firebase" import 'firebase/storage'; não está funcionando. Tive que usar o <span style="color: rgb(197, 134, 192);">import</span><span style="color: rgb(212, 212, 212);"> { </span><span style="color: rgb(156, 220, 254);">initializeApp</span><span style="color: rgb(212, 212, 212);"> } </span><span style="color: rgb(197, 134, 192);">from</span><span style="color: rgb(212, 212, 212);"> </span><span style="color: rgb(206, 145, 120);">'firebase/app'</span> <span style="color: rgb(197, 134, 192);">import</span><span style="color: rgb(212, 212, 212);"> { </span><span style="color: rgb(156, 220, 254);">getFirestore</span><span style="color: rgb(212, 212, 212);">, </span><span style="color: rgb(156, 220, 254);">collection</span><span style="color: rgb(212, 212, 212);">, </span><span style="color: rgb(156, 220, 254);">getDocs</span><span style="color: rgb(212, 212, 212);"> } </span><span style="color: rgb(197, 134, 192);">from</span><span style="color: rgb(212, 212, 212);"> </span><span style="color: rgb(206, 145, 120);">'firebase/firestore/lite'</span><span style="color:… Read more »
O firebase foi atualizado para a versão nova. Sendo assim, quem instalar o Firebase pelo expo install firebase instalará a versão 9 e dessa forma o arquivo firebaseConfig não funcionará do jeito apresentado nesse tutorial. Portanto para que funcione conforme apresentado aqui, utilze a versão anterior do firebase expo install firebase@8.2.3
Teria como voce disponibilizar o package.json desse projeto? so para as dependencias nao terem nenhum tipo de erro, e assim podemos focar somente no codigo… Faltou apenas isso no tutorial acima dele, disponibilizar o package.json
Tive esse erro, qual o problema???
Module not found: Can’t resolve ‘firebase’
1 | import firebase from “firebase”
2 | import ‘firebase/storage’;
3 |
4 | var firebaseConfig = {
Error from chokidar (C:\): Error: EBUSY: resource busy or locked, lstat ‘C:\pagefile.sys’
Error from chokidar (C:\Users): Error: UNKNOWN: unknown error, stat ‘C:\Users\All Users’
Por favor teria como voces disponibilizarem o package.json desse projeto? iria nos ajudar a nao termos erros com as dependencias que podem ter mudado com todo esse tempo… Agradeço desde ja! voces sao sensacionais!!!!
Firebase desatualizado, o atual está dando erro quando se fizer nesse seu método que funciona em uma versão anterior.