inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

Flutter로 SNS 앱 만들기

사용자 정보, 게시글 정보를 Model 클래스로 관리 강의 관련 질문

해결된 질문

364

강민석

작성한 질문수 4

0

안녕하세요.

강의 잘 듣고 있습니다.

사용자 정보, 게시글 정보를 Model 클래스로 관리 강의 관련 질문 있습니다.

그 전 강의인 firestore에 게시글 정보 저장 강의 까지는 firestore database에 정상적으로 data가 올라갔습니다.

하지만, 사용자 정보, 게시글정보를 Model 클래스로 관리 강의에 따라 코드 작성 후

firestore database에 data가 올라가지 않습니다.

(storage는 잘 작동합니다.)

//feed_model.dart
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:collection/collection.dart';
import 'package:sns_clonecode/models/urser_model.dart';

class FeedModel {
  final String uid;
  final String feedId;
  final String desc;
  final List<String> imageUrls;
  final List<String> likes;
  final int commentCount;
  final int likeCount;
  final Timestamp creatAt;
  final UserModel writer;

  const FeedModel({
    required this.uid,
    required this.feedId,
    required this.desc,
    required this.imageUrls,
    required this.likes,
    required this.commentCount,
    required this.likeCount,
    required this.creatAt,
    required this.writer,
  });

  Map<String, dynamic> toMap({
    required DocumentReference<Map<String, dynamic>> userDocRef,
  }) {
    return {
      'uid': this.uid,
      'feedId': this.feedId,
      'desc': this.desc,
      'imageUrls': this.imageUrls,
      'likes': this.likes,
      'commentCount': this.commentCount,
      'likeCount': this.likeCount,
      'creatAt': this.creatAt,
      'writer': userDocRef,
    };
  }

  factory FeedModel.fromMap(Map<String, dynamic> map) {
    return FeedModel(
      uid: map['uid'],
      feedId: map['feedId'],
      desc: map['desc'],
      imageUrls: List<String>.from((map['imageUrls'])),
      likes: List<String>.from((map['likes'])),
      commentCount: map['commentCount'],
      likeCount: map['likeCount'],
      creatAt: map['creatAt'],
      writer: map['writer'],
    );
  }
}
//user_model.dart
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';

class UserModel {
  final String uid;
  final String name;
  final String email;
  final String? profileImage;
  final int feedCount;
  final List<String> followers;
  final List<String> following;
  final List<String> likes;

  const UserModel({
    required this.uid,
    required this.name,
    required this.email,
    required this.profileImage,
    required this.feedCount,
    required this.followers,
    required this.following,
    required this.likes,
  });

  factory UserModel.init() {
    return UserModel(
      uid: '',
      name: '',
      email: '',
      profileImage: null,
      feedCount: 0,
      followers: [],
      following: [],
      likes: [],
    );
  }

//usermodle 이 가지고 있는 filed 변수로 가지고 있는 데이터들을 가지고 map 형태 데이터를 만들어 준다.
  Map<String, dynamic> toMap() {
    return {
      'uid': this.uid,
      'name': this.name,
      'email': this.email,
      'profileImage': this.profileImage,
      'feedCount': this.feedCount,
      'followers': this.followers,
      'following': this.following,
      'likes': this.likes,
    };
  }

//map 형태 데이터를 인자값을 전달 받아 usermolde 객체를 만들어 준다.
  factory UserModel.fromMap(Map<String, dynamic> map) {
    return UserModel(
      uid: map['uid'],
      name: map['name'],
      email: map['email'],
      profileImage: map['profileImage'],
      feedCount: map['feedCount'],
      followers: List<String>.from(map['followers']),
      following: List<String>.from(map['following']),
      likes: List<String>.from(map['likes']),
    );
  }
}

//feed_repository.dart

import 'dart:io';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:sns_clonecode/models/feed_model.dart';
import 'package:sns_clonecode/models/urser_model.dart';
import 'package:sns_clonecode/utils/logger.dart';
import 'package:uuid/uuid.dart';

class FeedRepository {
  final FirebaseStorage firebaseStorage;
  final FirebaseFirestore firebaseFirestore;

  const FeedRepository({
    required this.firebaseFirestore,
    required this.firebaseStorage,
  });

  Future<void> uploadFeed({
    required List<String> files,
    required String desc,
    required String uid,

//feeds 컬렉션에 저장
//피드 각각이 문서
//이미지는 storage에 직접 저장하고 firestore에 접근할 수 있는 url 문자열로 받을 것이다.
//좋아요 수
//이 게시글에 달린 댓글의 수
//게시글을 작성한 날짜
//feeds에서 user의 정보를 바로 가져올 수 있게 reference 타입의 데이터를 저장한다.
  }) async {
//파이어스토어에 데이터 저장하기위해서
//문서 아이디는 겹치지 않는 고유한 값으로 만들어야 한다.

//a-z 알파벳
//0~9 숫자
//이 두가지를 조합해서 32글자의 고유한 값을 만들어 준다.
//32글자에 - 4개씩 들어가서 36글자가 된다.
//고유한 값을 만드는 방법 여러가지 version1 ....
//우리는 version1을 사용 (현재 시간을 기준으로 random값을 만들어 준다.)

    String feedId = Uuid().v1();

    //firestore 문서 참조
    DocumentReference<Map<String, dynamic>> feedDocRef =
        firebaseFirestore.collection('feeds').doc(feedId);

    DocumentReference<Map<String, dynamic>> userDocRef =
        firebaseFirestore.collection('users').doc(uid);

    //storage 참조
    Reference ref = firebaseStorage.ref().child('feeds').child(feedId);

    List<String> imageUrls = await Future.wait(files.map((e) async {
      //문자열 e는 이미지 파일에 접근할 수 있는 경로
      String imageId = Uuid().v1();
      TaskSnapshot taskSnapshot = await ref.child(imageId).putFile(File(e));
      return await taskSnapshot.ref.getDownloadURL();
    }).toList());

    DocumentSnapshot<Map<String, dynamic>> userSnapshot =
        await userDocRef.get();

    UserModel userModel = UserModel.fromMap(userSnapshot.data()!);

    FeedModel feedModel = FeedModel.fromMap({
      'uid': uid,
      'feedId': feedId,
      'desc': desc,
      'imageUrls': imageUrls,
      'likes': [],
      'likeCount': 0,
      'commentCount': 0,
      'createAt': Timestamp.now(),
      'writer': userModel,
    });

    await feedDocRef.set(feedModel.toMap(userDocRef: userDocRef));

    // await feedDocRef.set({
    //   'uid': uid,
    //   'feedId': feedId,
    //   'desc': desc,
    //   'imageUrls': imageUrls,
    //   'likes': [],
    //   'commentCount': 0,
    //   'likeCount': 0,
    //   'creatAt': Timestamp.now(),
    //   'writer': userDocRef,
    // });

    await userDocRef.update({
      'feedCount': FieldValue.increment(1),
    });
  }
}

바쁘실 텐데 질문 읽어주셔서 감사합니다.

flutter android firebase dart

답변 2

0

DEV MOO

추가로 auth_repository.dart 의 signIn 함수 44행에 왜 로그아웃 하는지 모르겠다고 하셔서 설명 드립니다.

 

signInWithEmailAndPassword 함수를 호출하면 firebase 에 이메일이 등록되는 것과 동시에 자동으로 로그인이 됩니다.

 

이 앱은 이메일을 등록하고 메일 주소로 전송된 인증 링크를 클릭해야 회원가입이 완료되는 것이기에 이메일만 등록하고 인증 링크를 클릭하지 않은 사용자를 로그인 시켜서는 안되겠죠.

그래서 로그아웃 시키는 겁니다.

0

강민석

주석까지 답해주시니 감사합니다.

글 보고 잘 이해했습니다.

0

DEV MOO

오타 였습니다.

feed_model.dart 56행의

creatAt: map['creatAt'] 을 createAt: map['createAt'] 으로 수정 해주세요.

 

그리고 동일한 오타가 다른 곳에서도 발견되었는데 수정 하시는게 좋을 것 같습니다.

위치는 feed_model.dart 의 16, 27, 42 행 입니다.

1

강민석

오!!!! 감사합니다.

잘 작동합니다.

(혹시 오타일까 오늘 하루 종일 강의와 github 돌려보며 확인 했지만 발견하지 못 했었는데, 정말 감사합니다~!~!~!)

실수로 파이어프로젝트를 삭제하여 다시 살렸는데 profile screen이 에러입니다

0

153

1

파이어베이스 연동 중 Auth 및 ImagePicker 오류 발생, 도움 요청드립니다.

0

145

2

파이어베이스에서 실수로 강의프로젝트를 실수로 삭제하였습니다.도와주세요

0

169

2

파이어베이스 스토리지 설정에 프로젝트 업그레이드 라고 뜨는데 어떻게 하면됩니까

0

219

1

이거는 왜그렇죠

0

149

1

셋팅에 문제가생겼네요

0

142

2

마치면서 에러가 댓글가져오기와 좋아요 리스트 가져오기 에러

0

109

1

섹션15페이징기능_4프로필 화면에 페이징 적용

0

98

1

섹션15페이징기능_3좋아요 목록 화면에 페이징 적용

0

184

1

섹션14페이징기능_1게시글 목록 화면에 페이징 적용 feed_repository.dart에러

0

103

1

11셕션에서 좋아요.강의코드에서 좋아요 업데이트 문제 제대로 수정된건가요

0

122

1

12댓글화면_3댓글정보 가져오기

0

224

2

11댓글화면_댓글 정보 가져오기에서 콘솔에 commentList못찍고 있어요

0

81

1

섹션11 좋아요 목록화면에서 콘솔에서 FeedModel 데이터를 못가지고 있어요

0

89

1

섹션11 좋아요.누른 게시글 정보를 화면에표시에서 Exception 왜 발생합니까

0

146

0

Storage사용..?

0

903

2

10 게시물 화면에서 조금헷갈려서요

0

132

2

게시글 이미지 슬라이드 기능추가 carouselslider에러가 났습니다

0

144

1

섹션8 게시글 정보 화면에 표시

0

106

1

섹션8 게시글 정보가져오기

0

114

1

섹션8 게시글 정보 가져오기

0

90

1

섹션8 게시글 정보 가져오기 feedModel를 못받아오는것 같습니다.

0

123

1

메인화면에서 뒤로가기 눌렀을때 어플종료관련 건

0

182

1

섹션8 게시글 정보가져오기

0

161

2