Prequisites
[Demystifying Firebase (Part-1)] How to setup Firebase in React Native CLI App.
Suryansh Singh ・ Apr 5
[Demystifying Firebase (Part-2)] How to setup Firebase authentication in your react native app.
Suryansh Singh ・ Apr 6
- Basic Understanding of No-SQL Databases
Introduction
Looking for a database solution that keeps your app running smoothly, even offline? Enter Firestore, the cloud-based storage system that effortlessly syncs data across devices and offers real-time updates. In Part 3 of our series, we'll explore Firestore setup and learn how to leverage its power in our React Native projects.
Cloud Firestore Setup
Start by installing the Firestore package in your project:
npm install @react-native-firebase/firestore
- Navigate to your Firebase console and create a new database. Choose your server location and set your security rules according to your requirements. Once configured, your Firestore backend is ready to use.
- Voila! We are ready to use our backend, Click on Create Collection
- Lets name it posts
- Create a dummy document ID for now, or create your own document.
- You will see your
posts
collection along with dummy document.
Setting Up Our Utility functions
To simplify Firestore operations, let's set up utility functions in a firestore.js
file. These functions will handle CRUD operations and make data management a breeze.
import firestore from '@react-native-firebase/firestore';
const rootCollection = firestore();
export const getAllDocuments = async (collectionName) => {
try {
const collectionRef = rootCollection.collection(collectionName);
const querySnapshot = await collectionRef.get();
const collectionData = querySnapshot.docs.map(doc => ({
id: doc.id,
...doc.data(),
}));
return collectionData;
} catch (error) {
console.error(`Error fetching ${collectionName} data:`, error);
throw error;
}
};
export const createDocument = async (collectionName, documentData) => {
try {
const documentRef = rootCollection.collection(collectionName).doc();
const serverTimestamp = firestore.FieldValue.serverTimestamp();
const dataWithTimestamps = {
...documentData,
createdAt: serverTimestamp,
modifiedAt: serverTimestamp,
};
await documentRef.set(dataWithTimestamps);
return documentRef;
} catch (error) {
console.error('Error creating document:', error);
throw error;
}
};
export const readDocumentData = async (collectionName, documentId) => {
try {
const documentSnapshot = await rootCollection.collection(collectionName).doc(documentId).get();
if (documentSnapshot.exists) {
return documentSnapshot.data();
} else {
return null;
}
} catch (error) {
console.error('Error reading document data:', error);
throw error;
}
};
export const updateDocument = async (collectionName, documentId, updatedDocumentData) => {
try {
const serverTimestamp = firestore.FieldValue.serverTimestamp();
const dataWithTimestamps = {
...updatedDocumentData,
modifiedAt: serverTimestamp,
};
return rootCollection.collection(collectionName).doc(documentId).update(dataWithTimestamps);
} catch (error) {
console.error('Error updating document:', error);
throw error;
}
};
export const deleteDocument = async (collectionName, documentId) => {
try {
return rootCollection.collection(collectionName).doc(documentId).delete();
} catch (error) {
console.error('Error deleting document:', error);
throw error;
}
};
Simple Posts Screen
Now, let's put Firestore to work by creating a simple posts screen with complete CRUD operations. From fetching posts to adding, editing, and deleting them, you'll learn how to harness Firestore's flexibility and scalability.
import {View, Text, Button, FlatList} from 'react-native';
import React, {useEffect} from 'react';
import {
getAllDocuments,
createDocument,
updateDocument,
deleteDocument,
} from '../Firebase/firestore';
import { get } from 'react-native/Libraries/TurboModule/TurboModuleRegistry';
const PostsScreen = ({navigation}) => {
// State to store all posts
const [posts, setPosts] = React.useState([]);
// Fetch all posts from Firestore
const getAllPosts = async () => {
try {
const fetchedPosts = await getAllDocuments('posts');
console.log(fetchedPosts);
setPosts(fetchedPosts || []);
} catch (error) {
console.error('Error fetching posts:', error);
}
};
// Add a new post to Firestore
const addPost = async () => {
try {
await createDocument('posts', {
title: 'New Post',
content: 'This is a new post',
});
getAllPosts();
} catch (error) {
console.error('Error adding post:', error);
}
};
// Delete a post from Firestore
const deletePost = async postId => {
try {
await deleteDocument('posts', postId);
getAllPosts();
} catch (error) {
console.error('Error deleting post:', error);
}
};
// Update a post in Firestore
const updatePost = async postId => {
console.log('Updating post:', postId);
try {
await updateDocument('posts', postId, {
title: 'Updated Post',
content: 'This post has been updated',
});
const updatedPosts = posts.map(post => {
if (post.id === postId) {
return {
id: postId,
title: 'Updated Post',
content: 'This post has been updated',
};
}
return post;
});
getAllPosts();
} catch (error) {
console.error('Error updating post:', error);
}
};
// Fetch all posts from Firestore when the component mounts
useEffect(() => {
getAllPosts();
}, []);
return (
<View style={{flex: 1, alignItems: 'center'}}>
<Button title="Add Post" onPress={addPost} />
<Text
style={{
color: 'black',
margin: 10,
padding: 10,
fontSize: 20,
fontWeight: 'bold',
}}>
Posts
</Text>
<FlatList
data={posts}
ListEmptyComponent={() => (
<View style={{justifyContent: 'center', alignItems: 'center'}}>
<Text style={{color: 'black', fontSize: 18}}>No Posts Found</Text>
</View>
)}
renderItem={({item}) => (
<View
style={{
margin: 10,
padding: 10,
borderColor: 'black',
borderWidth: 1,
flexDirection: 'column',
}}>
<Text style={{color: "black", fontSize: 16, marginBottom:5}}>{item.title}</Text>
<Text style={{color: "gray", fontSize: 12, marginBottom:10}}>{item.content}</Text>
<Button
title="Edit Post"
onPress={() => updatePost(item.id)}
color={'purple'}
/>
<Button
title="Delete Post"
onPress={() => deletePost(item.id)}
color={'red'}
/>
</View>
)}
keyExtractor={(item, index) => (item.id || index).toString()}
/>
</View>
);
};
export default PostsScreen;
End Result
If you found value in this article, I'd love to hear your thoughts in the comments section! Your feedback fuels my motivation to create more content. If you're interested in learning more about Firestore or have specific topics you'd like me to cover, don't hesitate to let me know. Your input helps shape future articles and ensures they're tailored to your interests and needs. Thank you for reading!
Source : React Native Firebase