Firestore
Firestore adalah database NoSQL pada platform Firebase.
CRUD
Kita akan membuat aplikasi sederhana yang dapat melakukan operasi Create Read Update dan Delete ke Firestore.

Setup Firestore
Create Database
Pertama kita buat sebuah project di Firebase.

Kemudian pada menu sebelah kiri, klik menu Build - Firestore Database, dan klik tombol Create database.

Pada halaman Create database langkah 1, klik tombol Next. Pada langkah 2 pilih Start in production mode dan klik tombol Enable.
Update Rules
Pada halaman Cloud Firestore, klik menu Rules. Kemudian ubah false menjadi true pada baris ke 6 dan tekan tombol Publish.

Create Collection
Pada halaman Cloud Firestore, klik menu Data kemudian klik menu Start collection.

Isikan products pada Collection ID dan klik tombol Next. Pada halaman berikutnya, klik tombol Auto-ID pada Document ID dan buat field berikut ini:

Klik tombol Save.
Flutter Project
Buat project baru Flutter kemudian jalankan perintah berikut di terminal.
flutterfire configure
flutter pub add firebase_core
flutter pub add cloud_firestore
flutter pub add intl
Buka file android/app/build.gradle kemudian ubah minSdkVersion menjadi 21
minSdkVersion 21
Buka file android/app/src/main/AndroidManifest.xml dan tambahkan kode berikut diantara tag <manifest> dan <application>
<uses-permission android:name="android.permission.INTERNET" />
Main
Sesuaikan kode pada main.dart
| main.dart |
|---|
| import 'package:crud_products/firebase_options.dart';
import 'package:crud_products/pages/home_page.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Firestore CRUD',
home: HomePage(),
);
}
}
|
Home Page
Buat folder pages kemudian buat file home_page.dart.
| home_page.dart |
|---|
| import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// text fields' controllers
final TextEditingController _nameController = TextEditingController();
final TextEditingController _priceController = TextEditingController();
final CollectionReference _productss =
FirebaseFirestore.instance.collection('products');
var formatter = NumberFormat.decimalPatternDigits(
locale: 'id_ID',
decimalDigits: 0,
);
// Fungsi ini dijalankan saat floatting action button di tekan
// Menambahkan product jika tidak ada documentSnapshot yang dimasukkan sebagai parameter
// Jika documentSnapshot != null maka product yang ditampilkan akan di update
Future<void> _createOrUpdate([DocumentSnapshot? documentSnapshot]) async {
String action = 'create';
if (documentSnapshot != null) {
action = 'update';
_nameController.text = documentSnapshot['name'];
_priceController.text = documentSnapshot['price'].toString();
}
await showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext ctx) {
return Padding(
padding: EdgeInsets.only(
top: 20,
left: 20,
right: 20,
// prevent the soft keyboard from covering text fields
bottom: MediaQuery.of(ctx).viewInsets.bottom + 20),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
controller: _nameController,
decoration: const InputDecoration(labelText: 'Name'),
),
TextField(
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
controller: _priceController,
decoration: const InputDecoration(
labelText: 'Price',
),
),
const SizedBox(
height: 20,
),
ElevatedButton(
child: Text(action == 'create' ? 'Create' : 'Update'),
onPressed: () async {
final String? name = _nameController.text;
final int? price = int.tryParse(_priceController.text);
if (name != null && price != null) {
if (action == 'create') {
// Persist a new product to Firestore
await _productss.add({"name": name, "price": price});
}
if (action == 'update') {
// Update the product
await _productss
.doc(documentSnapshot!.id)
.update({"name": name, "price": price});
}
// Clear the text fields
_nameController.text = '';
_priceController.text = '';
// Hide the bottom sheet
if (!context.mounted) return;
Navigator.of(context).pop();
}
},
)
],
),
);
});
}
// Fungsi untuk menghapus product berdasarkan productId
Future<void> _deleteProduct(String productId) async {
await _productss.doc(productId).delete();
// Show a snackbar
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('You have successfully deleted a product')));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Firestore CRUD'),
),
// StreamBuilder digunakan untuk menampilkan semua product dari Firestore
body: StreamBuilder(
stream: _productss.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> streamSnapshot) {
if (streamSnapshot.hasData) {
return ListView.builder(
itemCount: streamSnapshot.data!.docs.length,
itemBuilder: (context, index) {
final DocumentSnapshot documentSnapshot =
streamSnapshot.data!.docs[index];
return Card(
margin: const EdgeInsets.all(10),
child: ListTile(
title: Text(documentSnapshot['name']),
subtitle: Text(formatter.format(documentSnapshot['price'])),
trailing: SizedBox(
width: 100,
child: Row(
children: [
// Tombol untuk edit product
IconButton(
icon: const Icon(Icons.edit),
onPressed: () =>
_createOrUpdate(documentSnapshot)),
// Tombol untuk menghapus product
IconButton(
icon: const Icon(Icons.delete),
onPressed: () =>
_deleteProduct(documentSnapshot.id)),
],
),
),
),
);
},
);
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
// Menambahkan product
floatingActionButton: FloatingActionButton(
onPressed: () => _createOrUpdate(),
child: const Icon(Icons.add),
),
);
}
}
|
Jalankan project.
Chalenge
Tambahkan konfirmasi saat data dihapus menggunakan package rflutter_alert

Final Project
Informasi mengenai final project dapat dilihat disini https://forms.gle/wPo8K4UoPaX1PxDN9