코딩하는 제리

[Flutter/Project](Instagram Clone) comment model 및 생성/업데이트 파일 본문

Flutter/Project_InstaClone(완)

[Flutter/Project](Instagram Clone) comment model 및 생성/업데이트 파일

JerryCho 2021. 3. 8. 16:53

models/firestore/comment_model.dart
repo/commnet_network_repository.dart
repo/helper/transformers.dart 파일에 추가
widgets/post.dart -> Comment 버튼 활성화 및 화면 이동

 


소스코드 및 pubspec.yaml

// models/comment_model.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_project_IJ/constants/firestore_keys.dart';

class CommentModel {
  final String username;
  final String userKey;
  final String comment;
  final DateTime commentTime;
  final String commentKey;
  final DocumentReference reference;

  // fromMap -> dart 내부 메서드
  CommentModel.fromMap(Map<String, dynamic> map, this.commentKey,
      {this.reference})
      : userKey = map[KEY_USERKEY],
        username = map[KEY_USERNAME],
        comment = map[KEY_COMMENT],
        commentTime = map[KEY_LASTCOMMENTTIME] == null
            ? DateTime.now().toUtc()
            : (map[KEY_LASTCOMMENTTIME] as Timestamp).toDate();

  // fromSnapshot -> cloud_firestore 메서드
  // snapshot -> FireStore 각각의 Document
  // id -> Document 키
  // reference -> 해당 Document 위치값
  // snapshot을 받아와서 PostModel로 변경.
  CommentModel.fromSnapshot(DocumentSnapshot snapshot)
      : this.fromMap(snapshot.data, snapshot.documentID,
            reference: snapshot.reference);

  // static은 인스턴스를 생성하지 않아도 호출이 가능함.
  // 포스트 데이터 생성.
  static Map<String, dynamic> getMapForNewComment(
      {String userKey, String username, String comment}) {
    Map<String, dynamic> map = Map();
    map[KEY_USERKEY] = userKey;
    map[KEY_USERNAME] = username;
    map[KEY_COMMENT] = comment;
    map[KEY_COMMENTTIME] = DateTime.now().toUtc();
    return map;
  }
}
// repo/comment_network_repository.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_project_IJ/constants/firestore_keys.dart';
import 'package:flutter_project_IJ/models/firestore/comment_model.dart';
import 'package:flutter_project_IJ/repo/helper/transformers.dart';

/* Create a comment
* 1. get post reference
* 2. get post snapshot
* 3. get/create comment collection
* 4. run transaction
* 4-1. upload comment data into comment collection
* 4-2. last comment data and num of comment in the post document
* */
class CommentNetworkRepository with Transformers {
  Future<void> createNewComment(
      String postKey, Map<String, dynamic> commentData) async {
    final DocumentReference postRef =
        Firestore.instance.collection(COLLECTION_POSTS).document(postKey);
    final DocumentSnapshot postSnapshot = await postRef.get();

    // comment를 저장할 Sub collection과 document 생성
    final DocumentReference commentRef =
        postRef.collection(COLLECTION_COMMENTS).document();

    return Firestore.instance.runTransaction((tx) async {
      if (postSnapshot.exists) {
        // comment reference 안에 comentData 저장
        await tx.set(commentRef, commentData);

        int numOfComments = postSnapshot.data[KEY_NUMOFCOMMENTS];
        await tx.update(postRef, {
          KEY_NUMOFCOMMENTS: numOfComments + 1,
          KEY_LASTCOMMENT: commentData[KEY_COMMENT],
          KEY_LASTCOMMENTTIME: commentData[KEY_COMMENTTIME],
          KEY_LASTCOMMENTOR: commentData[KEY_USERNAME],
        });
      }
    });
  }

  // 컬렉션 자체를 가져오기에 Stream 사용
  Stream<List<CommentModel>> fetchAllComments(String postKey) {
    return Firestore.instance
        .collection(COLLECTION_POSTS)
        .document(postKey)
        .collection(COLLECTION_COMMENTS)
        .orderBy(KEY_COMMENTTIME)
        .snapshots()
        // QuerySnapshot을 List<CommentModel>로 변경
        .transform(toComments);
  }
}

CommentNetworkRepository commentNetworkRepository = CommentNetworkRepository();
Comments