Halo teman – teman, karena sebelumnya kita sudah menghubungkan project dengan Firebase sebagai database (realtime database). Kali ini kita akan membangun CRUD dengan memanfaatkan realtime database ini.
Jadi pertama kita perlu menyiapkan file model yang berfungsi sebagai jembatan sebagai get, post dan update data. Sebelum itu, kita memerlukan file berikut pada direktori lib

Kenapa file nya di kelompokkan ke dalam folder? Ini bertujuan agar memudahkan dalam pembacaan kode serta mudah jika kita mengerjakan suatu project dalam kelompok atau singkatnya lebih mudah di pahami. Dengen mengelompokkan nya maka kita akan tau lebih cepat oh, ini file untuk ui.
Baik, lanjut ke model yang akan kita buat, di sini saya memberi nama file nya databrg.dart karena bertujuan untuk CRUD Data Barang itu sendiri
import 'package:firebase_database/firebase_database.dart';
class Barang {
final String? key;
String? namaBrg;
bool? favorite;
String? price;
String? stock;
String? desc;
Barang(
{this.key,
this.namaBrg,
this.favorite,
this.price,
this.stock,
this.desc});
Barang.fromSnapshot(DataSnapshot snapshot) : key = snapshot.key, //proses sending data ke realtime database
namaBrg = snapshot.value['namaBrg'],
favorite = snapshot.value['favorite'],
price = snapshot.value['price'],
stock = snapshot.value['stock'],
desc = snapshot.value['desc'];
Map<String, dynamic> toJson() => { //agar data dapat di baca dari bentuk Array ke bentuk JSON, karena flutter
'namaBrg' : namaBrg, //hanya dapat membaca data dalam bentuk JSON
'favorite' : favorite,
'price' : price,
'stock' : stock,
'desc' : desc,
};
}
Selanjutnya kita akan membuat file home_page.dart yang nantinya akan berfungsi menampilkan data sekaligus di sini kita juga akan menggunakan pop up untuk menambahkan data. Dan memanfaatkan Dismissible untuk menghapus data dengan slide ke kiri ataupun kanan
import 'dart:async';
import 'package:codingtalk_firebase_crud/model/databrg.dart';
import 'package:codingtalk_firebase_crud/ui/detail_page.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<Barang> _brgList = [];
final FirebaseDatabase _database = FirebaseDatabase.instance;
DatabaseReference? _brgRef;
final _namaBrgController = TextEditingController();
final _priceController = TextEditingController();
final _stockController = TextEditingController();
final _descController = TextEditingController();
StreamSubscription<Event>? _onBrgAddedSubscription;
StreamSubscription<Event>? _onBrgChangedSubscription;
@override
void initState() { //menjalankan proses saat terjadi perubahan data
_brgRef = _database.reference().child('brg');
_onBrgAddedSubscription = _brgRef?.onChildAdded.listen(_onNewBrg);
_onBrgChangedSubscription = _brgRef?.onChildChanged.listen(_onChangedBrg);
super.initState();
}
@override
void dispose() { //menghentikan semua proses ketika sudah tidak di page tsb agar tidak
_onBrgAddedSubscription?.cancel(); //memakan banyak srouce pada device
_onBrgChangedSubscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Data Storage App'),
),
body: Container(
child: _showBrgList(), //memisahkan data dalam bentuk fungsi widget, yg nantinya akan menampilkan data
), //tsb
floatingActionButton: FloatingActionButton(
onPressed: () {
_showDialogBrgForm(); //penjelasan sama dengan di atas
},
child: Icon(Icons.add),
),
);
}
Widget? _showBrgList() { //fungsi widget data menampilkan list barang
if (_brgList.length > 0) {
return ListView.builder(
itemCount: _brgList.length,
itemBuilder: (context, index) {
Barang barang = _brgList[index];
return Dismissible( //ini berfungsi untuk menghapus data dengan slide ke kiri ataupun kanan
key: Key(barang.key!),
background: Container(
color: Colors.red,
),
onDismissed: (direction) async {
if (_deleteBrg != null) {
_deleteBrg(barang.key!, index);
}
},
child: Card(
child: ListTile(
onTap: () {
//detail
Navigator.push(context, MaterialPageRoute(builder: (context)=>DetailPage(barang, _brgRef)));
},
title: Text(
barang.namaBrg ?? '-',
style: TextStyle(fontSize: 20, color: Colors.green),
),
subtitle: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Rp ${barang.price}',
style: TextStyle(fontSize: 12, color: Colors.black),
),
Text(
"Stock : ${barang.stock}",
style: TextStyle(fontSize: 12, color: Colors.black),
)
],
),
trailing: IconButton(
icon: (barang.favorite ?? false)
? Icon(
Icons.star,
color: Colors.yellowAccent,
size: 20,
)
: Icon(
Icons.star,
color: Colors.grey,
size: 20,
),
onPressed: () {
_updateFavorite(barang);
},
),
),
),
);
},
);
} else {
return Center(
child: Text('No Data Storage'),
);
}
}
void _showDialogBrgForm() { //fungsi widget pop up input data
_namaBrgController.clear();
_priceController.clear();
_stockController.clear();
_descController.clear();
showDialog(
context: context,
builder: (context) {
return AlertDialog(
scrollable: true,
content: Column(
children: [
TextField(
controller: _namaBrgController,
autofocus: true,
decoration: InputDecoration(labelText: 'Nama Barang'),
),
TextField(
controller: _priceController,
decoration: InputDecoration(labelText: 'Price'),
),
TextField(
controller: _stockController,
decoration: InputDecoration(labelText: 'Stock'),
),
TextField(
controller: _descController,
decoration: InputDecoration(labelText: 'Deskripsi'),
),
],
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Cancel'),
),
TextButton(
onPressed: () { //data akan di simpan ke database saat menekan button save
_addBrg(_namaBrgController.text, _priceController.text, _stockController.text, _descController.text);
Navigator.pop(context);
},
child: Text('Save'),
),
],
);
});
}
//listener
void _onNewBrg(Event event) {
setState(() {
_brgList.add(Barang.fromSnapshot(event.snapshot));
});
}
void _onChangedBrg(Event event) {
var oldEntry = _brgList.singleWhere((barang) {
return barang.key == event.snapshot.key;
});
setState(() {
_brgList[_brgList.indexOf(oldEntry)] =
Barang.fromSnapshot(event.snapshot);
});
}
//CRUD
Future<void> _deleteBrg(String key, int index) async {
await _brgRef?.child(key).remove();
setState(() {
_brgList.removeAt(index);
});
}
Future<void> _updateFavorite(Barang barang) async {
barang.favorite = !barang.favorite!;
await _brgRef?.child(barang.key!).set(barang.toJson());
}
Future<void> _addBrg(String namaBrg, String price,
String stock, String desc) async {
if (namaBrg.length > 0){
Barang barang = Barang(
namaBrg: namaBrg,
price: price,
stock: stock,
desc: desc,
favorite: false
);
await _brgRef?.push().set(barang.toJson());
}
}
}
Selanjutnya file detail_page.dart yang berguna menampilkan data barang secara detail, di sini kita hanya cukup mamanggil datanya saja untuk di tampilkan, selain itu juga ada pop up untuk mengedit data tersebut.
import 'package:codingtalk_firebase_crud/model/databrg.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
class DetailPage extends StatefulWidget{
final Barang? barang;
DatabaseReference? _brgRef;
DetailPage(this.barang, this._brgRef);
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
TextEditingController? namaBrgEdit;
TextEditingController? priceEdit;
TextEditingController? stockEdit;
TextEditingController? descEdit;
@override
void initState() {
namaBrgEdit = TextEditingController(text: widget.barang!.namaBrg);
priceEdit = TextEditingController(text: widget.barang!.price);
stockEdit = TextEditingController(text: widget.barang!.stock);
descEdit = TextEditingController(text: widget.barang!.desc);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(''),
),
body: ListView( //tampilan detail barang
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: Column(
children: [
Text('${widget.barang!.namaBrg}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),
SizedBox(height: 8,),
Text('${widget.barang!.price}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),
Divider(),
Column(
children: [
Text('Deskripsi produk', style: TextStyle(fontSize: 10),),
Text('${widget.barang!.desc}', style: TextStyle(fontSize: 10),)
],
)
],
),
),
)
],
),
floatingActionButton: FloatingActionButton( //menampilkan data yang akan di edit
onPressed: (){
_showDialogEdit(); //dibuatkan fungsi widget nya
},
child: Icon(Icons.edit),
),
);
}
void _showDialogEdit() { //fungsi widget untuk pop up update data
showDialog(
context: context,
builder: (context) {
return AlertDialog(
scrollable: true,
content: Column(
children: [
TextField(
controller: namaBrgEdit,
autofocus: true,
decoration: InputDecoration(labelText: 'Nama Barang'),
),
TextField(
controller: priceEdit,
decoration: InputDecoration(labelText: 'Price'),
),
TextField(
controller: stockEdit,
decoration: InputDecoration(labelText: 'Stock'),
),
TextField(
controller: descEdit,
decoration: InputDecoration(labelText: 'Deskripsi'),
),
],
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Cancel'),
),
TextButton( //data akan terupdate saat tombol save di tekan
onPressed: () {
_updateBrg(namaBrgEdit!.text, priceEdit!.text, stockEdit!.text, descEdit!.text, widget.barang?.favorite ?? false);
},
child: Text('Save'),
),
],
);
});
}
Future<void> _updateBrg (namaBrgEdit, priceEdit, stockEdit, descEdit, favorite) async {
Barang barang = Barang(
namaBrg: namaBrgEdit,
price: priceEdit,
stock: stockEdit,
desc: descEdit,
favorite: favorite
);
await widget._brgRef?.child(widget.barang!.key!).set(barang.toJson());
}
}
Jika sudah kita dapat melakukan running project, berikut demo aplikasinya serta tampilan realtime database pada firebase

Klik di sini untuk kembali ke Part 1