如何使用 flutter 检索 firestore 中的特定文档
How to retrieve a specific document in firestore with flutter
我正在尝试在我的应用程序中检索一个 firestore 文档,以便我可以更新它。这是当前代码:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
MyApp(),
);
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Baby Names',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Baby Name Votes')),
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('baby').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return _buildList(context, snapshot.data.documents);
},
);
}
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
return ListView(
padding: const EdgeInsets.only(top: 20.0),
children: snapshot.map((data) => _buildListItem(context, data)).toList(),
);
}
Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
final record = Record.fromSnapshot(data);
final docID = record.reference.documentID;
return Padding(
key: ValueKey(record.name),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: ListTile(
title: Text(record.name),
trailing: Text(record.votes.toString()),
onTap: () {
print('Here is the record you have just clicked on: $docID, ${record.name}, ${record.votes}');
showModalBottomSheet(
context: context,
builder: (context) => EditVoteScreen(),
);
},
),
),
);
}
}
class EditVoteScreen extends StatefulWidget {
@override
_EditVoteScreenState createState() => _EditVoteScreenState();
}
class _EditVoteScreenState extends State<EditVoteScreen> {
String newBabyName = 'Gregg';
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff757575),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Edit A Baby Name'),
SizedBox(height: 20.0),
Text(
'Current Name: ${record.name}',
),
SizedBox(height: 20.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Change Baby Name To:',
),
SizedBox(
width: 20.0,
),
DropdownButton<String>(
value: newBabyName,
icon: Icon(Icons.arrow_drop_down_circle),
iconSize: 24,
elevation: 16,
underline: Container(
height: 1,
color: Color(0xFF150A42),
),
onChanged: (String newValue) {
setState(() {
newBabyName = newValue;
});
},
items: <String>['Gregg', 'Mikey', 'Joey', 'Dave']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
],
),
SizedBox(height: 20.0),
FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0)),
color: Color(0xFF150A42),
textColor: Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: Text(
' Save Changes',
),
),
onPressed: () {},
),
],
),
),
);
}
}
class Record {
final String name;
final int votes;
final DocumentReference reference;
Record.fromMap(Map<String, dynamic> map, {this.reference})
: assert(map['name'] != null),
assert(map['votes'] != null),
name = map['name'],
votes = map['votes'];
Record.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
@override
String toString() => "Record<$name:$votes>";
}
firestore 数据库只有两个字段。下面是一些示例数据:name: 'James' (String), and votes: 2 (number)
当您在应用程序中单击一条记录时,我设法让它在控制台中打印出 docID,以及名称和投票。问题是,我怎样才能将我刚刚单击的文档显示在 ModalBottomSheet 中,以便更新名称字段?
如果我能让它显示在 ModalBottomSheet 的名称字段中,我应该能够自己弄清楚如何更新它。但我什至都在努力让它出现在那里!我当前的代码显示错误 undefined name 'record'.
如有任何帮助,我们将不胜感激!
谢谢
贾森
您需要向 EditVoteScreen 小部件添加一个构造函数并传入文档的信息,以便您可以在 EditVoteScreen 的构建方法中使用它:
class EditVoteScreen extends StatefulWidget {
final Record record;
const EditVoteScreen({Key key, this.record}) : super(key: key);
@override
_EditVoteScreenState createState() => _EditVoteScreenState();
}
创建时传入记录 class:
showModalBottomSheet(
context: context,
builder: (context) => EditVoteScreen(record: record,),
);
然后在状态class中通过引用widget变量来引用它。
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Edit A Baby Name'),
SizedBox(height: 20.0),
Text(
'Current Name: ${widget.record.name}', // Here
),
我正在尝试在我的应用程序中检索一个 firestore 文档,以便我可以更新它。这是当前代码:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
MyApp(),
);
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Baby Names',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Baby Name Votes')),
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('baby').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return _buildList(context, snapshot.data.documents);
},
);
}
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
return ListView(
padding: const EdgeInsets.only(top: 20.0),
children: snapshot.map((data) => _buildListItem(context, data)).toList(),
);
}
Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
final record = Record.fromSnapshot(data);
final docID = record.reference.documentID;
return Padding(
key: ValueKey(record.name),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: ListTile(
title: Text(record.name),
trailing: Text(record.votes.toString()),
onTap: () {
print('Here is the record you have just clicked on: $docID, ${record.name}, ${record.votes}');
showModalBottomSheet(
context: context,
builder: (context) => EditVoteScreen(),
);
},
),
),
);
}
}
class EditVoteScreen extends StatefulWidget {
@override
_EditVoteScreenState createState() => _EditVoteScreenState();
}
class _EditVoteScreenState extends State<EditVoteScreen> {
String newBabyName = 'Gregg';
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff757575),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Edit A Baby Name'),
SizedBox(height: 20.0),
Text(
'Current Name: ${record.name}',
),
SizedBox(height: 20.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Change Baby Name To:',
),
SizedBox(
width: 20.0,
),
DropdownButton<String>(
value: newBabyName,
icon: Icon(Icons.arrow_drop_down_circle),
iconSize: 24,
elevation: 16,
underline: Container(
height: 1,
color: Color(0xFF150A42),
),
onChanged: (String newValue) {
setState(() {
newBabyName = newValue;
});
},
items: <String>['Gregg', 'Mikey', 'Joey', 'Dave']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
],
),
SizedBox(height: 20.0),
FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0)),
color: Color(0xFF150A42),
textColor: Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: Text(
' Save Changes',
),
),
onPressed: () {},
),
],
),
),
);
}
}
class Record {
final String name;
final int votes;
final DocumentReference reference;
Record.fromMap(Map<String, dynamic> map, {this.reference})
: assert(map['name'] != null),
assert(map['votes'] != null),
name = map['name'],
votes = map['votes'];
Record.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
@override
String toString() => "Record<$name:$votes>";
}
firestore 数据库只有两个字段。下面是一些示例数据:name: 'James' (String), and votes: 2 (number)
当您在应用程序中单击一条记录时,我设法让它在控制台中打印出 docID,以及名称和投票。问题是,我怎样才能将我刚刚单击的文档显示在 ModalBottomSheet 中,以便更新名称字段?
如果我能让它显示在 ModalBottomSheet 的名称字段中,我应该能够自己弄清楚如何更新它。但我什至都在努力让它出现在那里!我当前的代码显示错误 undefined name 'record'.
如有任何帮助,我们将不胜感激!
谢谢
贾森
您需要向 EditVoteScreen 小部件添加一个构造函数并传入文档的信息,以便您可以在 EditVoteScreen 的构建方法中使用它:
class EditVoteScreen extends StatefulWidget {
final Record record;
const EditVoteScreen({Key key, this.record}) : super(key: key);
@override
_EditVoteScreenState createState() => _EditVoteScreenState();
}
创建时传入记录 class:
showModalBottomSheet(
context: context,
builder: (context) => EditVoteScreen(record: record,),
);
然后在状态class中通过引用widget变量来引用它。
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Edit A Baby Name'),
SizedBox(height: 20.0),
Text(
'Current Name: ${widget.record.name}', // Here
),