React native에서는 React Query가 있어서 디따 편하게 했는데;;; 찾아보니까 Flutter에는 대표적으로 사용되는 React Query처럼 대표적으로 많이 사용되는 패키지는 없는 듯해... 음 뭐 그렇다고 Firestore 테스트를 못할 건 아니니까! 프로젝트 구조적으로 개판이되서 글치.. 암튼 고고.. 달려!
우선 Firebase console 설정부터!
그리고 걍 프로덕션 모드에서 시작하기 선택(로그인하면 DB 접근 가능)하고 다음
그리고 DB 위치를 선택해야 하는데 asia-northeast3가 서울 리젼이니까 난 이거 선택했음. 그런데 실제로 배포할 때는 여러가지 고려할 게 많겠지 주요 사용자의 위치라던지, 리전마다 DB 가격도 틀리니깐! (서울 리젼이 조금 비쌌던 걸로 기억함.)
사용 설정을 누르면 이제 DB는 준비가 끝났어. 이제 앱에서 접근해볼거야. cloud_firestore 패키지 설치부터👇
%flutter pub add cloud_firestore
그리고 TextField와 ElevatedButton을 만들어서 버튼을 누르면 TextField에 입력된 Text를 firestore에 업로드 하도록 만들어 볼거야.👇👇
class ScreenA extends StatelessWidget {
...
//TextField controller
final inputController = TextEditingController();
//버튼에 물릴 텍스트 업로드 함수!
void fbstoreWrite() {
//"user@email.com" 컬렉션에 {userText:유저가 입력한 텍스트} 문서 추가!
FirebaseFirestore.instance
.collection(FirebaseAuth.instance.currentUser!.email.toString())
.add({'userText': inputController.text})
.then((value) => print("document added")) //잘 들어갔니?
.catchError((error) => print("Fail to add doc ${error}")); //에러가 있니?
}
...
//텍스트를 입력햇!
TextField(
controller: inputController,
decoration: InputDecoration(
border: OutlineInputBorder(), label: Text("텍스트를 입력하세요.")),
),
//버튼을 눌러서 업로드 햇!
ElevatedButton(
//onPressed 함수를 물려줬!
onPressed: () => fbstoreWrite(), child: Text("Text Upload")),
...
그리고 테스트를 해봅시다. 아래와 같이 "핼로우 월드" 입력하고 Text Upload 버튼을 누르면!👇
Firebase console에서 DB에 핼로우 월드 문서가 잘 생성된 걸 확인할 수 있어.👇
여기서 끝내지 말고 읽어오는 것도 해보자구. 일단 단순하게 읽어오는 것부터! 그럴려면 읽어온 데이터를 저장할 State가 필요할 것 같아. 그러니까 Text 박스 하나랑 읽어오는 버튼 하나로 구성된 단순한 StatefulWidget을 하나 만들거야.
먼저 유저 텍스트 업로드 함수에 데이터 정렬을 위한 timeStamp를 하나 추가해줬음.👇
...
void fbstoreWrite() {
FirebaseFirestore.instance
.collection(FirebaseAuth.instance.currentUser!.email.toString())
//timeStamp 추가!
.add({'userText': inputController.text, 'createdAt': Timestamp.now()})
.then((value) => print("document added"))
.catchError((error) => print("Fail to add doc ${error}"));
}
...
그 다음에 위에서 말한 StatefulWidget도 새로 만들어서 넣어줬어!👇
class FirestoreRead extends StatefulWidget {
const FirestoreRead({super.key});
@override
State<FirestoreRead> createState() => _FirestoreReadState();
}
class _FirestoreReadState extends State<FirestoreRead> {
Map<String, dynamic> FirebaseLastDocument = {'userText': ""};
void readFbLastDoc() {
FirebaseFirestore.instance
.collection(FirebaseAuth.instance.currentUser!.email.toString())
.orderBy('createdAt')//생성된 시간으로 정렬해서
.limitToLast(1)//뒤에서 1개 읽어옴.
.get()
.then((value) {
setState(() {//setState!
FirebaseLastDocument = value.docs[0].data();
});
print("data: ${FirebaseLastDocument['userText']}");
}).catchError((onError) => print("error ${onError}"));
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
Text(FirebaseLastDocument['userText']),//userText 출력!
ElevatedButton(
//버튼 누르면 읽어왓!
onPressed: () => readFbLastDoc(), child: Text("Read Last FB Doc"))
],
));
}
}
그리고 나서 테스트해보면 잘 동작하는 걸 확인할 수 있다구!
여기까지는 잘 동작했는데 읽어오기 버튼 눌러서 읽어오는 거 말고 실시간으로 읽어올 수 있는지 확인해 볼래.
class FirestoreRead extends StatefulWidget {
const FirestoreRead({super.key});
@override
State<FirestoreRead> createState() => _FirestoreReadState();
}
class _FirestoreReadState extends State<FirestoreRead> {
//user email 컬렉션을 스트림으로 선언!!
final Stream<QuerySnapshot> userTextStream = FirebaseFirestore.instance
.collection(FirebaseAuth.instance.currentUser!.email.toString())
.snapshots();
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: userTextStream,//스트림 연결!
builder: (context, snapshot) {
if (!snapshot.hasData) {// 데이터 없으면!!
return Text("There is no data!");
}
if (snapshot.hasError) {// 에러 있으면!!
return Text("Failed to read the snapshot");
}
return Expanded(
child: ListView(//리스트뷰 써보자! 왜냐면 데이터가 많을 거니까!
shrinkWrap: true,//이거 없으면 hasSize에서 에러발생!!
//snapshot을 map으로 돌려버림!
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data() as Map<String, dynamic>;
return ListTile(title: Text(data['userText']));//Listtile 생성!
}).toList(),//map을 list로 만들어서 반환!
),
);
},
);
}
}
테스트를 해보면 실시간으로 추가된 데이터를 읽어온다~ 음~ 매우 흡족하구만!! 그런데 데이터를 순서대로 안읽어오네?
Snapshot에다가 orderby()를 추가해주면 될까? ㅇㅇ 됨.
final Stream<QuerySnapshot> userTextStream = FirebaseFirestore.instance
.collection(FirebaseAuth.instance.currentUser!.email.toString())
.orderBy('createdAt')// 이렇게 추가 해버렷!
.snapshots();
이 정도면 flutter 위에서 기본은 다 해본거 같아. 이제 심화학습? 노노! 바로 프로젝트 돌입이지! ㅋㅋㅋ 나중에 문제가 많이 될거라고? ㅋㅋㅋㅋㅋ 응~ 그 문제 해결하는 것도 배워야지 ㅋㅋㅋ 자 이제 달려보자구! ㅋㅋㅋ
'Flutter > Flutter Study' 카테고리의 다른 글
[Flutter] GetX (0) | 2022.10.17 |
---|---|
[Flutter] JSON, 직렬화???, Model, Firestore withConverter (1) | 2022.10.15 |
[Flutter] - Firebase auth! 소셜 로그인 (0) | 2022.10.12 |
[Flutter] - Firebase auth! 이메일 로그인. (0) | 2022.10.11 |
React Native에서 Flutter로 갈아타기 #9 - Navigation 두번째 (0) | 2022.10.11 |