Firebase Flutter Services
This Flutter project demonstrates Firebase integration for Firestore CRUD operations, Firebase Authentication (Auth) for user registration and login, and Firebase Storage for uploading images.
Getting started
In your flutter project add the dependency:
dependencies:
flutter_firebase_services: ^0.0.4
Import package:
import 'package:firebase_service/firebase_service.dart';
Usage
Create an instanse
Db db = Db();
Firestore CRUD Operations
Create Document
To add a new document to a Firestore collection:
// Sample code for creating a document
await db.addDocument(
collectionName: 'users',
data: {'name': 'John Doe', 'age': 25},
);
Read
to read all documents in a collection
StreamBuilder(
stream: db.getDocumentsStream(collectionName: "users"),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
List<DocumentSnapshot> documents = snapshot.data?.docs ?? [];
return ListView.builder(
itemCount: documents.length,
itemBuilder: (context, index) {
Map<String, dynamic> data =
documents[index].data() as Map<String, dynamic>;
return ListTile(
title: Text(data['name']),
subtitle: Text("${data['age']}"),
);
},
);
},
),
sample model
class User {
final String id;
final String name;
final int age;
final String imageURL;
User({required this.id, required this.name, required this.age, required this.imageURL});
//the fromMap method must have id
factory User.fromMap(String id, Map<String, dynamic> map) {
return User(
id: id,
name: map['name'] ?? '',
age: map['age'] ?? 0,
imageURL: map['imageURL'] ?? '',
);
}
}
to retrieve all the documents as a List of Models
StreamBuilder(
stream: db.getDocumentsAsModelsStream<User>(
collectionName: 'users',
fromMap: (documentId, data) => User.fromMap(documentId, data),
),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
List<User> users = snapshot.data ?? [];
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
User user = users[index];
return ListTile(
title: Text('Name: ${user.name}'),
subtitle: Text('Age: ${user.age}'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserDetailPage(docid: user.id),
));
},
);
},
);
},
),
Read Document
to retrieve a document as a model
StreamBuilder(
stream: db.getDocumentAsModelStream(
collectionName: "users", documentId: docid, fromMap: User.fromMap),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
User? user = snapshot.data;
if (user == null) {
return const Center(child: Text('User not found'));
}
return ListTile(
title: Text("Name: ${user.name}"),
subtitle: Text("Age: ${user.age}"),
);
},
),
To retrieve documents from a Firestore collection based on a condition:
StreamBuilder(
stream: db.getDocStreamWhere(
collectionName: "users",
field: "age",
isEqualTo: 25, // Replace with the desired condition
),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
List<DocumentSnapshot> documents = snapshot.data?.docs ?? [];
return ListView.builder(
itemCount: documents.length,
itemBuilder: (context, index) {
Map<String, dynamic> data =
documents[index].data() as Map<String, dynamic>;
return ListTile(
title: Text(data['name']),
subtitle: Text("${data['age']}"),
);
},
);
},
),
update Document
to update a document based on document id
// Sample code for updating a document
await db.updateDocument(
collectionName: 'users',
documentId: 'documentId123',
data: {'age': 26},
);
to update documents based on a condition
await updateWhere(
collectionName: 'your_collection_name',
field: 'your_field',
isEqualTo: 'your_value',
dataToUpdate: {'fieldToUpdate': 'new_value'},
);
Delete Document
to delete a document based on document id
// Sample code for deleting a document
await db.deleteDocument(
collectionName: 'users',
documentId: 'documentId123',
);
to delete documents based on a condition
await deleteWhere(
collectionName: 'your_collection_name',
field: 'your_field',
isEqualTo: 'your_value',
);
Firebase Auth
Register
to register using email and password
await db.register(email, password);
Login
to login using email and password
await db.login(email, password);
Signout
to signout from the firebase auth
await db.signOut();
Firebase Storage
Upload Image
to Upload an image to firebase storage
import 'dart:io';
import 'package:crud/db.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class UploadImageToFirebase extends StatefulWidget {
const UploadImageToFirebase({super.key});
@override
State<UploadImageToFirebase> createState() => _UploadImageToFirebaseState();
}
class _UploadImageToFirebaseState extends State<UploadImageToFirebase> {
XFile? selectedImage;
Db db = Db();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Upload Image"),
),
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (selectedImage != null) Image.file(File(selectedImage!.path)),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
_pickImage();
},
child: const Text('Pick Image'),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () async {
String url = await db.uploadImage(
file: selectedImage!,
folderName: "Images",
fileName: "Image Name");
},
child: const Text('Upload Image To Firebase Storage')),
],
),
),
),
);
}
// Method to pick image in flutter
Future<void> _pickImage() async {
final XFile? image =
await ImagePicker().pickImage(source: ImageSource.camera);
if (image != null) {
setState(() {
selectedImage = image;
});
}
}
}
Upload Image in Web
to upload an image when building a website
Reference: https://flutterappcode.com/flutter-web-how-to-upload-image-to-firebase/
import 'package:file_picker/file_picker.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class UploadImageToFirebase extends StatefulWidget {
const UploadImageToFirebase({super.key});
@override
State<UploadImageToFirebase> createState() => _UploadImageToFirebaseState();
}
class _UploadImageToFirebaseState extends State<UploadImageToFirebase> {
String _imageFile = ''; // Variable to hold the selected image file
Uint8List? selectedImageInBytes;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Upload Image"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_imageFile.isNotEmpty || _imageFile != '')
Image.memory(selectedImageInBytes!),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Calling pickImage Method
pickImage();
},
child: const Text('Pick Image'),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () async {
// Calling uploadImage Method
await uploadImage(selectedImageInBytes!);
},
child: const Text('Upload Image To Firebase Storage')),
],
),
),
);
}
// Method to pick image in flutter web
Future<void> pickImage() async {
try {
// Pick image using file_picker package
FilePickerResult? fileResult = await FilePicker.platform.pickFiles(
type: FileType.image,
);
// If user picks an image, save selected image to variable
if (fileResult != null) {
setState(() {
_imageFile = fileResult.files.first.name;
selectedImageInBytes = fileResult.files.first.bytes;
});
}
} catch (e) {
// If an error occured, show SnackBar with error message
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("Error:$e")));
}
}
}