Created
March 11, 2021 16:20
-
-
Save edward1986/423f891e5a277d7ef19f4edcf1be664b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:cloud_firestore/cloud_firestore.dart'; | |
import 'package:firebase_core/firebase_core.dart'; | |
import 'package:flutter/material.dart'; | |
import 'PeopleList.dart'; | |
import 'PeopleUpsert.dart'; | |
void main() async { | |
WidgetsFlutterBinding.ensureInitialized(); | |
await Firebase.initializeApp(); | |
runApp(Main(),); | |
} | |
class Main extends StatefulWidget { | |
@override | |
_MainState createState() => _MainState(); | |
} | |
class _MainState extends State<Main> { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Chapter 12 Firebase', | |
theme: ThemeData( | |
primarySwatch: Colors.amber, | |
), | |
routes: <String, WidgetBuilder>{ | |
'/': (BuildContext ctx) => Landing(), | |
'/peopleUpsert': (BuildContext ctx) => PeopleUpsert(), | |
'/peopleList': (BuildContext ctx) => PeopleList(), | |
}, | |
initialRoute: '/peopleList', | |
); | |
} | |
} | |
class Landing extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('Ajax and Firebase'), | |
), | |
body: Container( | |
color: Colors.amber, | |
), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:cloud_firestore/cloud_firestore.dart'; | |
import 'package:flutter/material.dart'; | |
import 'Person.dart'; | |
class PeopleList extends StatefulWidget { | |
@override | |
_PeopleListState createState() => _PeopleListState(); | |
} | |
class _PeopleListState extends State<PeopleList> { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('People Maintenance'), | |
), | |
body: body, | |
floatingActionButton: FloatingActionButton( | |
onPressed: () { | |
Navigator.pushNamed(context, '/peopleUpsert'); | |
}, | |
child: Icon(Icons.add), | |
), | |
); | |
} | |
Widget get body { | |
return StreamBuilder<QuerySnapshot>( | |
stream: fetchPeople(), | |
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) { | |
if (snapshot.hasError) { | |
return Text('Oh no! Error! ${snapshot.error}'); | |
} | |
if (!snapshot.hasData) { | |
return const Text('No people found'); | |
} | |
final List<Widget> widgets = | |
snapshot.data.docs.map<Widget>((DocumentSnapshot p) { | |
final Person person = Person.fromDocumentSnapshot(p); | |
return InkWell( | |
child: GestureDetector( | |
onTap: () { | |
print('tapped'); | |
Navigator.pushNamed<dynamic>(context, '/peopleUpsert', | |
arguments: person) | |
.then((dynamic person) { | |
print( | |
'Do something with person returned: ${person | |
.name['first']}'); | |
}); | |
}, | |
child: Container( | |
margin: const EdgeInsets.all(5.0), | |
child: Stack( | |
children: <Widget>[ | |
if (person.imageUrl != null && person.imageUrl.length > 0) | |
Image.network(person.imageUrl, | |
height: 300, width: 300, fit: BoxFit.cover) | |
else | |
Image.asset('assets/images/NoImage.jpg'), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |
children: <Widget>[ | |
Flexible( | |
child: Text( | |
'${p['name']['first']} ${p['name']['last']}', | |
style: Theme | |
.of(context) | |
.textTheme | |
.title | |
.copyWith(color: Colors.white), | |
), | |
), | |
IconButton( | |
icon: Icon( | |
Icons.delete, | |
color: Colors.white, | |
), | |
onPressed: () { | |
deletePerson(person); | |
}, | |
) | |
], | |
), | |
Align( | |
alignment: Alignment.bottomLeft, | |
child: Text( | |
p['email'], | |
style: Theme | |
.of(context) | |
.textTheme | |
.title | |
.copyWith(color: Colors.white), | |
), | |
), | |
], | |
), | |
), | |
), | |
); | |
}).toList(); | |
return GridView.extent( | |
maxCrossAxisExtent: 300, | |
children: widgets, | |
); | |
}, | |
); | |
} | |
Stream<QuerySnapshot> fetchPeople() { | |
return FirebaseFirestore.instance | |
.collection('people') | |
.limit(100) | |
.snapshots(); | |
} | |
void deletePerson(Person personToDelete) { | |
FirebaseFirestore.instance | |
.collection('people') | |
.doc(personToDelete.documentID) | |
.delete() | |
.catchError((dynamic error) { | |
print('Error! $error'); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:cloud_firestore/cloud_firestore.dart'; | |
import 'Person.dart'; | |
class PeopleUpsert extends StatefulWidget { | |
@override | |
_PeopleUpsertState createState() => _PeopleUpsertState(); | |
} | |
class _PeopleUpsertState extends State<PeopleUpsert> { | |
final GlobalKey<FormState> _key = GlobalKey<FormState>(); | |
Person _person; | |
@override | |
Widget build(BuildContext context) { | |
_person = ModalRoute | |
.of(context) | |
.settings | |
.arguments; | |
_person = (_person == null) ? Person() : _person; | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text( | |
'People Maintenance', | |
), | |
), | |
body: _body, | |
floatingActionButton: FloatingActionButton( | |
onPressed: () { | |
_key.currentState.save(); | |
updatePersonToFirestore(_person); | |
Navigator.pop<Person>(context, _person); | |
}, | |
child: Icon(Icons.save), | |
), | |
); | |
} | |
Widget get _body { | |
return Form( | |
key: _key, | |
child: Container( | |
padding: const EdgeInsets.all(20), | |
child: Column( | |
children: <Widget>[ | |
personFormField( | |
labelText: 'First name', initialValue: _person.name['first']), | |
personFormField( | |
labelText: 'Last name', initialValue: _person.name['last']), | |
personFormField(labelText: 'Email', initialValue: _person.email), | |
personFormField( | |
labelText: 'Image URL', initialValue: _person.imageUrl), | |
], | |
)), | |
); | |
} | |
Widget personFormField( | |
{String labelText, String fieldName, String initialValue}) { | |
return TextFormField( | |
initialValue: initialValue, | |
decoration: InputDecoration(labelText: labelText), | |
onSaved: (String val) { | |
switch (labelText) { | |
case 'First name': | |
_person.name['first'] = val; | |
break; | |
case 'Last name': | |
_person.name['last'] = val; | |
break; | |
case 'Email': | |
_person.email = val; | |
break; | |
case 'Image URL': | |
_person.imageUrl = val; | |
break; | |
default: | |
throw "Bad person field name. I don't know $labelText"; | |
} | |
}, | |
); | |
} | |
void updatePersonToFirestore(Person person) { | |
FirebaseFirestore.instance | |
.collection('people') | |
.doc(_person.documentID) | |
.set(<String, dynamic>{ | |
'name': person.name, | |
'email': person.email, | |
'imageUrl': person.imageUrl, | |
}).then<void>((dynamic doc) { | |
print('Document successfully written! $doc'); | |
}).catchError((dynamic error) { | |
print('Error! $error'); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:cloud_firestore/cloud_firestore.dart'; | |
class Person { | |
Person() { | |
name = <String, String>{}; | |
} | |
Person.fromJson(Map<String, dynamic> data) { | |
name = data['name']; | |
email = data['email']; | |
imageUrl = data['imageUrl']; | |
} | |
Person.fromDocumentSnapshot(DocumentSnapshot data) { | |
documentID = data.id; | |
imageUrl = data['imageUrl']; | |
email = data['email']; | |
name = <String, String>{ | |
'first': data['name']['first'], | |
'last': data['name']['last'] | |
}; | |
} | |
String documentID; | |
Map<String, String> name; | |
String email; | |
String imageUrl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment