예전 버전의 firebase랑 flutter 쓰는 강의 보면서 끄적대고 있었는데
어떤 개발자 형님이 "Provider"라는 라이브러리를 써서 streaming 상태를 제어하던데..
저도 따라 써봤거든요..
근데.. 얘네도 firebase의 업데이트를 따라가는 게 여간 어려운 게 아닌가 봐요,, 어느 선 넘어가니깐 호환이 안 됨;;
그래도 적당히.. docs 읽어보면서 끼워 맞춰봤어오..
1. Firestore, Provider 설치
pubspec.yaml 파일에 다음과 같이 추가하"거나"
dependencies:
.
.
.
provider: ^6.0.5
cloud_firestore: ^4.3.1
.
.
.
밑의 내용을 터미널에 입력해주시면 됩니당
flutter pub add provider
flutter pub add cloud_firestore
2. Firestore in Flutter - Provider
Firebase 콘솔에 들어가보면 아마 firestore 사용할 거냐고 물어볼 텐데, 그거 동의하고 하시면 됩니다.
아마 규칙 설정에서 초반에 false로 되어있는 경우가 있을 텐데 해당 부분 true로 바꾸면 read/write할 수 있습니당~

더 자세한.. 규칙 설정은 몰라요..;;
- firestore에서 데이터 불러오는 서비스파일 (보통 database.dart라고 명명하더라구요)
import 'package:cloud_firestore/cloud_firestore.dart';
class DatabaseService {
final String? uid;
DatabaseService({ this.uid });
final CollectionReference collection_data = FirebaseFirestore.instance.collection("컬렉션 이름");
Stream<QuerySnapshot<Map<String, dynamic>?>?> get docs {
return collection_data.snapshots() as Stream<QuerySnapshot<Map<String, dynamic>?>?>;
}
}
- 이 클래스는 uid(user_id)를 바탕으로 운영할 데이터 서비스 클래스인데 일단 건너뛰어도 돼요
- 그 아래에 collection 이름을 넣음으로서 firestore의 데이터에 접근할 수 있는데 뭐 미리 생성해 놓은 collection을 넣으시면 됩니당~ (콘솔을 이용하면 쉽게 데이터 삽입하고 수정하고 지울 수 있어욤)
- 마지막으로 collection의 snapshot을 받아올 때 스트림 객체를 반환하는데 그걸 "저희가 예상하는 타입의 형태"로 받고 함수로 반환해주면 됩니당(아마 dynamic 타입으로 받을 수? 있을 거에요?!?? 근데 잘 모르겠음 ㄹㅇ..)
- database 서비스 파일 호출 후 클래스 객체 생성
import 'package:provider/provider.dart';
import 'database.dart 파일의 path';
위젯 {
return StreamProvider<QuerySnapshot<Map<String, dynamic>?>?>.value(
initialData: null,
value: DatabaseService().docs,
child: ~~~~~~~
)
}
- 만든 파일 임포트하고 StreamProvider에 넣을 객체를 명세해 줍니다.
- 아까 docs getter 메소드 하나 만들었으니까 그걸 적용하는 stream을 return하도록 구조를 짭니다..
- 그래서 child 파라미터에 넘겨지는 다른 위젯에서 context의 형태로 해당 stream 객체를 불러올 수 있게 됩니다!!!
말이 너무 어렵네요.. 솔직히 저도 잘 모름.. 그냥 컴퍼일러의 눈을 피해서.. 슥슥 해버렸네요,,🤭
- Stream Provider로 넘긴 데이터 사용
import 'package:provider/provider.dart';
위젯 {
final docs = Provider.of<QuerySnapshot<Map<String, dynamic>?>?>(context);
for (var doc in docs!.docs){
doc.data()?.forEach((key, value) {
if (key == "name"){
print("$key, $value");
}
});
}
}
뭐 대충 이런 식으로 사용이 가능하다는 이야기..
근데 이게 가장 큰 단점이 뭐냐면요,, 이 데이터를 List 형태로 못 바꿔요;; 정확히는 안 바꿔져요;; 이것 땜시 엄청 낑낑댔어요,,
이게 그 초입에 말한 호환 부분;;

3. Firesotre in Flutter - pure flutter
그렇다면 우짤까요,, 그래도 List 형태가 나중 가서도 편할텐데 말이죠 허허,,
생각해낸 해결 방안 (flutter 자체 stream builder 사용)
서비스 파일.dart는 버려주시고 View를 붙일 위젯에 아래와 같이 작성해 줍니다.
위젯 {
final _colStream = FirebaseFirestore.instance.collection("컬렉션 이름").snapshots();
return StreamBuilder<QuerySnapshot>(
stream: _colStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (BuildContext context, int index) {
var doc = snapshot.data!.docs[index];
var data = doc.data() as Map;
return Text(data['칼럼 이름']);
},
);
},
);
}
이렇게 하면.. 좀 지저분해지긴 해도 쓸만한 Stream 위젯이.. 완성됩니다..
코드.. 솔직히 별건 없고.. snapshot.data!.docs 부분이 List 자료구조를 반환하는 점을 이용하여..
Stream에 index별로 itemCount: list의 length만큼 굴리라는 의미입니다..
=> 즉 해당 Streambuilder는 입력한 컬렉션 안의 모든 문서(id에 상관없이)의 내용을 가져와서 전달하게 됩니다..
=> "Provider 안쓰고"
당연히 stream인 만큼.. firebase에서 변화가 일어난 부분을 빠릿빠릿하게 가져와서 바꿔주는 기능을.. 잘 수행합니다..
provider.. 갖다 버려.. 팍씨..
라고 하고 싶지만~ 이런 부분 빼면 괜찮게 작동하는 거 같아서 계속 데리고 써보려구요 ㅎㅎ..
(첨언)
?
데이터를 받을 때.. 모델을 구조화해서 받는 법도 있다는데 그건.. 정말 다음에..
?
참고 자료
https://firebase.google.com/docs/firestore/query-data/listen?hl=ko
Cloud Firestore로 실시간 업데이트 받기 | Firebase
Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기 이 페이지는 Cloud Translation API를 통해 번역되었습니
firebase.google.com
'대학생활' 카테고리의 다른 글
Firebase + Flutter - 초기 셋팅 (1) | 2023.01.30 |
---|---|
[Python] 주소 공공데이터 좌표 변환 with Google map (0) | 2023.01.28 |
[Ruby] Rails with Devise + MyPage (0) | 2023.01.03 |
[Python] gRPC server run with database (0) | 2023.01.02 |
[Docker] 도커에 관한 이야기 (0) | 2022.11.26 |