Building a Flutter Firebase Firestore CRUD App

    In this tutorial, we will walk you through the process of creating a Flutter application that performs CRUD (Create, Read, Update, Delete) operations on a list of items using Firebase Firestore. Firestore is a cloud-based NoSQL database provided by Firebase, and Flutter is a powerful open-source framework for building cross-platform mobile apps. By combining these technologies, you can create a real-time and cloud-synced list management app. 


Prerequisites

Before we start, ensure that you have the following prerequisites in place:


Adding Dependencies

First, we need to add the necessary dependencies to our Flutter project. Open your project's pubspec.yaml file and add the following dependencies:


dependencies:

  flutter:

    sdk: flutter

  firebase_core: ^latest_version

  cloud_firestore: ^latest_version


Replace latest_version with the actual latest versions of the firebase_core and cloud_firestore packages available on the Flutter packages website (https://pub.dev/).


After adding the dependencies, run the following command in your terminal to fetch and install them:

flutter pub get

Configuring Firebase
To configure Firebase for your Flutter project, follow these steps:

  • Go to the Firebase Console (https://console.firebase.google.com/).
  • Create a new project if you haven't already.
  • Add your Flutter app to the project by clicking on the "Add App" button. Follow the on-screen instructions to register your app with Firebase.
  • Download the google-services.json file and place it in the android/app directory of your Flutter project for Android, or the ios/Runner directory for iOS.
  • Initialize Firebase in your Flutter app by opening your main.dart file and adding the following code in the main() function:


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}


Building the Flutter App
Now, let's dive into building the Flutter app with Firebase Firestore integration. We'll provide code snippets along with explanations for each step.

1. Create a Flutter App
Start by creating a new Flutter app using the flutter create command or your preferred IDE.

2. Create Firebase Project
Follow the previous section to create a Firebase project and add the necessary configuration to your Flutter app.

3. Design the User Interface
In your lib/main.dart file, design the user interface for your app. Here's a simple example:

import 'dart:io';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_example/firebase_options.dart';
import 'package:flutter/material.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();

await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firestore Example',
home: MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
final FirebaseFirestore firestore = FirebaseFirestore.instance;
final TextEditingController textEditingController = TextEditingController();

@override
void initState() {
super.initState();
}

void _addItem() async {
if (textEditingController.text.isNotEmpty) {
await firestore
.collection('items')
.add({'name': textEditingController.text});
//_fetchData();
textEditingController.clear();
}
}

Future<void> deleteItem(String documentId) async {
try {
await FirebaseFirestore.instance
.collection('items')
.doc(documentId)
.delete();
print('Item deleted successfully');
} catch (e) {
print('Error deleting item: $e');
}
}

Future<void> _showDeleteConfirmationDialog(String documentId) async {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Delete Item'),
content: Text('Are you sure you want to delete this item?'),
actions: <Widget>[
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('Delete'),
onPressed: () {
deleteItem(documentId);
Navigator.of(context).pop();
},
),
],
);
},
);
}

Future<void> _showEditItemDialog(String documentId, String itemName) async {
textEditingController.text = itemName;

return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Edit Item'),
content: TextField(
controller: textEditingController,
decoration: InputDecoration(labelText: 'Edit Item'),
),
actions: <Widget>[
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('Save'),
onPressed: () async {
String updatedName = textEditingController.text;
await FirebaseFirestore.instance
.collection('items')
.doc(documentId)
.update({'name': updatedName});
textEditingController.clear();
Navigator.of(context).pop();
},
),
],
);
},
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Firestore Example'),
),
body: Column(
children: <Widget>[
TextField(
controller: textEditingController,
decoration: InputDecoration(labelText: 'Enter Item'),
),
ElevatedButton(
onPressed: _addItem,
child: Text('Add Item'),
),
Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('items')
.snapshots(),
builder:
(context, AsyncSnapshot<QuerySnapshot> streamSnapshot) {
return ListView.builder(
itemCount: streamSnapshot.data!.docs.length,
itemBuilder: (context, index) {
final DocumentSnapshot documentSnapshot =
streamSnapshot.data!.docs[index];
// return InkWell(
// onTap: () {
// // deleteItem(documentSnapshot.id);
//
// _showDeleteConfirmationDialog(documentSnapshot.id);
// },
// child: Text(streamSnapshot.data!.docs[index]['name']));

return ListTile(
title: Text(streamSnapshot.data!.docs[index]['name']),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.edit),
onPressed: () {
setState(() {
_showEditItemDialog(documentSnapshot.id,
documentSnapshot['name']);
textEditingController.clear();
});
},
),
IconButton(
icon: Icon(Icons.delete),
onPressed: () {
_showDeleteConfirmationDialog(
documentSnapshot.id);
},
),
],
),
);
},
);
})),
],
),
);
}
}

Conclusion

In this tutorial, we've created a Flutter app that seamlessly integrates Firebase Firestore, enabling users to perform CRUD operations on a list of items. We've provided code explanations and highlighted essential functionalities for adding, editing, and deleting items.


You can find the complete code in the provided snippet above. Feel free to use it as a reference or customize it to meet your project's specific requirements. This app serves as a solid foundation for building more advanced Firestore-based applications.


Happy coding!



Comments

Popular posts from this blog

Unlocking the Power of OOP: A Beginner's Guide to Objects, Encapsulation, Inheritance, Abstraction, and Polymorphism

HTTP GET Response in Flutter