Flutter examples for personal use of widget templates, firebase use examples, providers, and more!
FlutterFire is a set of Flutter plugins which connect your Flutter application to Firebase (https://firebase.flutter.dev/docs/overview/)
- Install Firebase CLI (https://firebase.google.com/docs/cli#install-cli-windows)
- Install FlutterFire CLI
dart pub global activate flutterfire_cli
- Run
flutterfire configure
in your project root directory <<< Step (1) if you've done this before - Do the configuration (remove iOS if you want)
- You should have
firebase_options.dart
inside lib/ - Get firebase_core
flutter pub add firebase_core
(needed dependency infirebase_options.dart
) (You should havegenerated_plugin_registrant.dart
as well) Step (2) - Call
Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
before starting the app <<< Step (3)
See lib/firebase_examples/firebase_auth/
Dependencies:
- Configure FlutterFire (See FlutterFire Setup)
flutter pub add firebase_core
flutter pub add firebase_auth
Instructions:
- Initialize Firebase before you runApp():
Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
- Sign-In:
await FirebaseAuth.instance.signInWithEmailAndPassword(email: 'jeremy.tubongbanua@gmail.com', password: 'lemon1234');
- Create:
await FirebaseAuth.instance.createUserWithEmailAndPassword(email: 'jeremy.tubongbanua@gmail.com', password: 'lemon1234');
See lib/widget_examples/snackbar/
Method examples: lib/widget_examples/snackbar/snackbar_util.dart
Raw Example:
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message)));
See lib/widget_examples/drawer/
Template: lib/widget_examples/drawer/drawer.dart
Raw Example:
Scaffold(
drawer: Drawer(...) // see template: lib/widget_examples/drawer/drawer.dart
)
See lib/widget_examples/bottom_navigation_bar/
Tabs Screen template: lib/widget_examples/bottom_navigation_bar/tabs_screen.dart
Raw Example:
Scaffold(
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex, // 0 <= x <= items.length;
items: [/* ... Insert Widgets ...*/],
onTap: () {
setState((index) {
_currentIndex = index;
});
}
)
)
See lib/firebase_examples/firebase_cloud_firestore/ \
Dependencies:
- Configure FlutterFire (See FlutterFire Setup)
flutter pub add firebase_core
flutter pub add cloud_Firestore
Tips:
- Access instance through
FirebaseFirestore.instance
- Collections hold documents
- Documents hold field-value pairs and hold collections
- https://firebase.flutter.dev/docs/firestore/usage#document--query-snapshots (TODO)
Instructions:
- Initialize Firebase
Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
- Set (removes other data in the document):
final Map<String, dynamic> data = {'field': 'value'};
await FirebaseFirestore.instance
.collection('collectionId')
.doc('documentId')
.set(data);
- Update (does not remove other data in the document):
final Map<String, dynamic> data = {'field': 'value', 'lemon': 5};
await FirebaseFirestore.instance
.collection('collectionId')
.doc('documentId')
.update(data);
- Get:
final documentSnapshot = await FirebaseFirestore.instance.collection('users').doc('user1').get();
print(documentSnapshot.data()); // {lemon: 5, test: 3}
- Add:
- creates collection (if necessary)
- creates document with auto-id
await FirebaseFirestore.instance.collection('poopy').add({'test': 3})
- StreamBuilder + Snapshots: Sample: users (collection) > x23mark (document) >
StreamBuilder(
stream: FirebaseFirestore.instance.collection('users').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return const Text('Snapshot has error?');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
return ListView(
children: snapshot.data!.docs
.map((DocumentSnapshot document) => ListTile(
title: Text(document.data().toString()),
))
.toList(),
);
},
),
-
FutureBuilder (TODO) https://firebase.flutter.dev/docs/firestore/usage#one-time-read
-
Checking if a document exists:
final CollectionReference collection = await FirebaseFirestore.instance.collection('users'); // get collection reference
final DocumentReference document = collection.doc('x23mark'); // get document reference
final DocumentSnapshot snapshot = await document.get(); // get snapshot
final bool hasData = snapshot.data() != null; // hasData ?
- Getting document data:
final CollectionReference collection = await FirebaseFirestore.instance.collection('users'); // get collection reference
final DocumentReference document = collection.doc('x23mark'); // get document reference
final DocumentSnapshot snapshot = await document.get(); // get document snapshot
final Object? data = snapshot.data()?; // get nullable Object
print(data); // {nickname: jeremy}
- Steps 8 and 10 together
final CollectionReference collection = await FirebaseFirestore.instance.collection(collectionIdcontroller.text);
final DocumentReference document = collection.doc(documentIdController.text);
final DocumentSnapshot snapshot = await document.get();
final bool hasData = snapshot.data() != null;
if (hasData) {
document.update({fieldController.text: valueController.text});
} else {
document.set({fieldController.text: valueController.text});
}
-
Converters (TODO) https://firebase.flutter.dev/docs/firestore/usage#typing-collectionreference-and-documentreference
-
Removing Data (TODO) https://firebase.flutter.dev/docs/firestore/usage#typing-collectionreference-and-documentreference
See lib/other_examples/multi_provider/ \
Dependencies:
$ flutter pub add provider
Tips:
- Providers are good for app-wide data
- Provider flutter package makes life easy
Instructions:
- Create a class that uses the
ChangeNotifier
mixin. (Use keywordwith
butextends
works as well to get access to notifyListeners()).
Example:
import 'package:flutter/material.dart';
class CountProvider with ChangeNotifier {
late int _currentCount;
CountProvider() {
_currentCount = 0;
}
void increment() {
_currentCount += 1;
notifyListeners();
}
void decrement() {
_currentCount -= 1;
notifyListeners();
}
int get currentCount {
return _currentCount;
}
}
- Initialize Provider
final ChangeNotifierProvider<CountProvider> provider = ChagneNotifierProvider<CountProvider>(create: (context) => CountProvider());
- a) Shove it into the MultiProvider
app
is a MaterialApp.
final MultiProvider providers = MultiProvider(providers: [provider], child: app);
- b) Use a singular provider
app
is a MaterialApp.
final ChangeNotifierProvider<CountProvider> provider = ChagneNotifierProvider<CountProvider>(create: (context) => CountProvider(), child: app);
-
Call
runApp(providers)
(or `runApp(provider) for 3b). -
Use
ChangeNotifierProvider.value(...)
for Provider classes that are instantiated frequently.
See lib/other_examples/fonts/
Instructions:
- Add font files to project. See
lib/other_examples/fonts/assets/
for font file examples. - Register fonts into
pubspec.yaml
accordingly. (*font weight is findable via the place you downloaded the font).
fonts:
- family: Quicksand
fonts:
- asset: assets/fonts/Quicksand-Light.ttf
weight: 300
- asset: assets/fonts/Quicksand-Regular.ttf
weight: 400
- asset: assets/fonts/Quicksand-Medium.ttf
weight: 500
- asset: assets/fonts/Quicksand-Semibold.ttf
weight: 600
- asset: assets/fonts/Quicksand-Bold.ttf
weight: 700