## 해당 TIL은 주어진 과제를 수행하면서 얻은 학습 내용과, 시행착오 등등을 종합해서 작성한것임
1. 파이어베이스 데이터 업데이트
파이어베이스에서 데이터를 업데이트 하는 방법은 다음과 같다.
'chatroom' 컬렉션의 chatroom_id 문서에서 data중 수정할 key 값의 value를 update로 넘겨주면 간단하게 수정할 수 있다.
Future<void> updateById(String chatroom_id, String nickname) async {
FirebaseFirestore firestore = FirebaseFirestore.instance;
CollectionReference collectionRef = firestore.collection('chatroom');
final docRef = collectionRef.doc(chatroom_id);
Map<String, dynamic> data = {
"update_date": DateTime.now().toIso8601String(),
};
await docRef.update(data);
}
그런데?
만약 데이터구조가 이런식일때, body의 안의 요소를 업데이트 하고 싶다면 어떻게 해야 할까?
{
"chatroom_id": "ABCD",
"update_date": DateTime.now(),
"password": "1111",
"body" : [
{
"nickname" : "tester",
}
]
}
원래라면, 수정전의 값을 가져와서 body에 수정값을 넣은 새로운 body를 만든다음, body에 집어넣어주는 번거로운 일을 해야 하는데(이러한 작업을 하려다가 시간만 잡아먹고 다른 방법이 없는지 찾아보았다..)
다행히도 파이어베이스는 이럴때 사용하는 메서드를 제공해 준다.
파이어 베이스가 제공하는 FieldValue 요소를 사용하면, 원래의 데이터 값을 건들이지 않고, 원하는 부분만 수정이 가능하다!!
Future<void> updateById(String chatroom_id, String nickname) async {
FirebaseFirestore firestore = FirebaseFirestore.instance;
CollectionReference collectionRef = firestore.collection('chatroom');
final docRef = collectionRef.doc(chatroom_id);
Map<String, dynamic> data = {
"update_date": DateTime.now().toIso8601String(),
"body": FieldValue.arrayUnion([
{"nickname": nickname}
])
};
await docRef.update(data);
}
2. DB - 스트림 연결하기
일반적인 Future를 이용한 한번 DB를 읽는 방법은 다음과 같다.
'chatroom' 컬렉션의 chatroom_id 문서에 있는 모든 데이터를 읽어와 List<ChatroomModel> 형태로 반환하는 메서드이다.
Future<List<ChatroomModel>> getById(String query) async {
FirebaseFirestore firestore = FirebaseFirestore.instance;
CollectionReference collectionRef = firestore.collection('chatroom');
QuerySnapshot snapshot = await collectionRef.get();
List<QueryDocumentSnapshot> documentSnapshots = snapshot.docs;
final docs = documentSnapshots.where((e) {
return e.id.contains(query);
});
final list = docs.map((e) {
final map = e.data() as Map<String, dynamic>;
final newMap = {
'chatroom_id': e.id,
...map,
};
return ChatroomModel.fromJson(newMap);
}).toList();
// 정렬
list.sort((a, b) => a.update_date.compareTo(b.update_date));
final orderList = list.reversed.toList();
return orderList;
}
실시간 DB를 읽어서 값을 받아오는 스트림은, 마찬가지로 일단 DB를 읽는방식이기 때문에, 코드상의 배치는 비슷하다.
다만, 여기서 추가되는점은, DB의 변화를 알 수 있게끔 하기 위한 Snapshot을 스트림으로 사용하는것이다.
Stream<List<ChatroomModel>> getByIdStream(String query) {
FirebaseFirestore firestore = FirebaseFirestore.instance;
CollectionReference collectionRef = firestore.collection('chatroom');
final stream = collectionRef.snapshots();
final newStream = stream.map((snapshot) {
final docs = snapshot.docs.where((doc) {
return doc.id.contains(query);
});
final list = docs.map((doc) {
final map = doc.data() as Map<String, dynamic>;
final newMap = {
'chatroom_id': doc.id,
...map,
};
return ChatroomModel.fromJson(newMap);
}).toList();
// 정렬
list.sort((a, b) => a.update_date.compareTo(b.update_date));
final orderList = list.reversed.toList();
return orderList;
});
return newStream;
}
해당 스트림을 사용할때는 다음과 같이 사용한다.
// 스트림을 통해 실시간 채팅방 리스트 가져오기
void streamSetChatRoom(String title){
final chatroomRepo = ChatroomRepo();
final stream = chatroomRepo.getByIdStream(title);
final streamSubscription = stream.listen((chatroom){
state = DetailState(state.bottomNavigationBarSelectedIndex, chatroom, state.selectedImagePath);
});
ref.onDispose((){
print('스트림 종료');
streamSubscription.cancel();
});
}
그리고 스트림이 시작할 타이밍에
해당 코드를 넣어주면, 스트림이 시작된다.
streamSetChatRoom(title);
'TIL' 카테고리의 다른 글
TIL - SPRINCHAT(팀프로젝트) (1) <Chat_bubbles 라이브러리, Stack의 Overflow> (0) | 2024.12.12 |
---|---|
TIL - 지역 검색 앱(5) <Firebase DB와 Realtime DB 의 차이점> (0) | 2024.12.06 |
TIL - 지역 검색 앱 (3) <AlertDialog의 context, 파이어스토리지에 에셋이미지 업로드하기> (0) | 2024.12.04 |
TIL - 지역 검색 앱 (2) <파이어베이스 TimeStamp, 다트 DateTime> (0) | 2024.12.03 |
TIL - 지역 검색 앱 (1) <RiverPod의 로직 순서> (0) | 2024.12.02 |