One-time Read - get()
Collection 또는 document를 한번만 콜 하려면, Query.get or DocumentReference.get method를 사용하면 됩니다!
class GetUserName extends StatelessWidget {
final String documentId;
GetUserName(this.documentId);
@override
Widget build(BuildContext context) {
CollectionReference users = FirebaseFirestore.instance.collection('users');
return FutureBuilder<DocumentSnapshot>(
future: users.doc(documentId).get(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Something went wrong");
}
if (snapshot.hasData && !snapshot.data!.exists) {
return Text("Document does not exist");
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>;
return Text("Full Name: ${data['full_name']} ${data['last_name']}");
}
return Text("loading");
},
);
}
}
여기서 FutureBuilder를 사용했는데
snapshot.data 가 futurebuilder로 받아온 데이터를 의미하고
(여기서는 Data의 타입이 DocumentReference 일 것이다.)
고로 snapshot.data.data()은 DocumentSnapshot의 Document Data 전체를 가져올 수 있다.
이 때 Data를 as Map으로 해줘도 되고
받아오는 변수를 var로 선언해줘도 된다.
하지만 var 변수는 가독성이 떨어지기 때문에 Map<String,dynamic>으로 타입을 정하는 것을 권장한다.
Realtime changes - snapshot()
Both the CollectionReference & DocumentReference provide a snapshots() method which returns a Stream:
Realtime 변수는 Streambuilder 함수를 사용해서 가져올 수 있다.
Stream collectionStream = FirebaseFirestore.instance.collection('users').snapshots();
Stream documentStream = FirebaseFirestore.instance.collection('users').doc('ABC123').snapshots();
(Streambuilder 사용 예제)
class UserInformation extends StatefulWidget {
@override
_UserInformationState createState() => _UserInformationState();
}
class _UserInformationState extends State<UserInformation> {
final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance.collection('users').snapshots();
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _usersStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
return ListTile(
title: Text(data['full_name']),
subtitle: Text(data['company']),
);
}).toList(),
);
},
);
}
}
여기서는 snapshot()으로 stream에 해당하는 Data를 가져왔으므로
Streambuilder를 사용해야한다.
snapshot.data.docs는 곧, List<Documentsnapshot>를 의미한다.
여기서 forEach 와 fromDocumentShapshot 함수를 잘 이용하면 model class를 객체화 시킬 때 유용하다.
+추가적으로
Flutter State management 인 Bloc or Getx 등을 사용하면 사실 Stream을 쓸 일이 많지 않으니 get()을 잘 봐두자!
'Flutter > Firebase' 카테고리의 다른 글
[FIREBASE] IOS, Android Firebase ERROR 없이 한번에 연결하기 (0) | 2021.11.30 |
---|---|
[Firebase] Firebase Storage (0) | 2021.11.20 |
[Firebase] Firebase property 정리 (0) | 2021.11.19 |
[Firebase] IOS 연결하기 (0) | 2021.11.10 |
[Firebase] Android 연결하기 (0) | 2021.11.03 |