Create beautiful Flutter widget trees using this handy Firestore builder widget.
Extras
Using VS Code? There is a snippets extension for Firefly!
Usage
There is three steps to start using Firefly.
Setup Firebase
We recommend following the FlutterFire guide to setup your app with Firebase.
It´s important to setup Firebase before using any Firefly widgets.
We like to use a FutureBuilder to initialize Firebase.
Widget build(BuildContext context) {
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
return FutureBuilder(
// Initialize FlutterFire:
future: _initialization,
builder: (context, snapshot) {
// Check for errors
if (snapshot.hasError) {
return Text('THERE WAS AN ERROR...');
}
// Once complete, show your application
if (snapshot.connectionState == ConnectionState.done) {
return FireflyApp();
}
// Otherwise, show something whilst waiting for initialization to complete
return Text('LOADING...');
},
);
}
Use the FireflyProvider
The FireflyProvider
will provide all Firefly widgets with the correct instance of your Firestore database. It also needs a list of FireflyDataBuilder
. The purpose of the FireflyDataBuilder is to provide Firefly with the correct model and constuctor so it can create your objects before you can access them in the various builder parameters.
class FireflyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final firestore = FirebaseFirestore.instance;
final buildList = [
FireflyDataBuilder(
model: Person,
builder: (json) => Person.fromJson(json),
)
];
return FireflyProvider(
instance: firestore,
modelbuilderList: buildList,
child: App(),
);
}
}
Finally, you can use Firefly
Firefly
requires two things to work correctly.
The collection
parameter is used so Firefly knows which Firestore Collection to retrive data from.
The type object expected to accessed in the various builder
parametes. Here we expect a Person by adding <Person>
We can then use the builder
to get a list of Person
objects, here described as state
.
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Firefly<Person>(
collection: 'persons',
builder: (context, state) => ListView.builder(
itemCount: state.length,
itemBuilder: (context, index) => Text(state[index].name),
),
),
),
);
}
}
Using the Firefly widget
The Firefly widget has a bunch of parameters:
listBuilder
The builder
is one way to use retrive the created objects. But you can also use the shorthand listBuilder
to get a already created ListView
with objects.
You can´t combine many builders, so remember to only use one per Firefly widget.
Firefly<Person>(
collection: 'persons',
listBuilder: (context, state, index) => Text(state[index].name),
),
Querying
You can also query the Firestore directly on the widget. Use the query
parameter and the Query
model.
Just make sure you hide the Firestore Query in your import with:
import 'package:cloud_firestore/cloud_firestore.dart' hide Query;
Firefly<Person>(
collection: 'persons',
listBuilder: (context, state, index) => Text(state[index].name),
queries: [Query('age')..isEqualTo(22)],
),
Default queries can be defined on the FireflyProvider. These will be applied on all usages of the Firefly widget.
FireflyProvider(
defaultQueries: [Query('age')..isEqualTo(22)],
instance: FirebaseFirestore.instance,
modelbuilderList: [...],
child: ...
),
Override Loading
Want to show another widget when the Firestore is loading. Just override the loading
parameter with any widget you like.
Firefly<Person>(
collection: 'players',
listBuilder: (context, state, index) => Text(state[index].name),
loading: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
Handle Errors
If you get an error receiving your data, handle it with the error
parameter.
Firefly<Person>(
collection: 'players',
listBuilder: (context, state, index) => Text(state[index].name),
error: (error) => Text(error.toString()),
),