본문 바로가기

Flutter/12 Clone 'Used Goods app'

[Flutter] Clone - 당근마켓21(userModel)

이번에는 Firebase 에 저장할 사용자 정보(userModel)에 대한 모델링을 구현해보겠습니다.

개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 3.0.1

 

 

모델링을 할때, 저는 2가지 방법을 비교해보고 진행합니다.

첫번째는 " https://app.quicktype.io/"  사이트를 이용하는 방법.

두번째는 안드로이드 스튜디오의 플러그인 "Json to Dart"  입니다.

선호하는 방식은 첫번째 입니다.

 

첫번째 방식은 아래 링크 설명을 참고하세요

2022.06.30 - [Flutter/04 Widgets] - [Flutter] Widgets - Google map 2

 

[Flutter] Widgets - Google map 2

이번 카테고리는 google map 을 사용하는 방법에 대해서 알아보겠습니다. 개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 3.0.1 소스코드 위치 - https://github.com/mike-bskim/google_map_test/releases/t..

unsungit.tistory.com

 

 

두번째 방식은 아래 링크 설명을 참고하세요

2022.04.28 - [Flutter/10 app Weather] - [Flutter] App Weather - 3.5단계 model of openweathermap

 

[Flutter] App Weather - 3.5단계 model of openweathermap

이번에는 데이터 모델을 만드는 방법에 대해서 알아보겠습니다. 개발환경 : 윈도우11, 안드로이드 스튜디오(Arctic Fox 2020.3.1 Patch 4), flutter 2.8.1 소스코드 위치 - Release data_model · mike-bskim/wea..

unsungit.tistory.com

 

 

 

사용한 패키지는 아래와 같습니다.

 

geoflutterfire: ^3.0.3

 

 

 

user_model.dart - 모델링시 주요 포인트는 아래와 같습니다.

1. GeoFirePoint 사용방법 및 DateTime 처리 방법( toUtc() / toDate()  )

- fromJson

 

 

- toJson

 

 

 

 

2. UserModel 과 UserModel1 는 데이터 전달과정에서 몇가지 차이가 있다. 

UserModel - UserModel.fromSnapshot 함수를 이용한 직접 처리

                     UserModel userModel = UserModel.fromSnapshot(documentSnapshot);

UserModel1 - 2번으로 나눠서 처리.

                    UserModel1 userModel1 = UserModel1.fromJson(documentSnapshot.data()!);
                    userModel1.reference = documentSnapshot.reference;

 

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:geoflutterfire/geoflutterfire.dart';

import '../constants/data_keys.dart';

// json to Dart 플러그인을 사용한 모델링, 일부분은 직접 수정함
class UserModel {
  late String userKey;
  late String phoneNumber;
  late String address;
  late num lat;
  late num lon;
  late GeoFirePoint geoFirePoint;
  late DateTime createdDate;

  // firestore 에서 데이터를 가져요거나, document 데이터를 가져오는 경우라면
  // DocumentReference 를 넣어줄수 있다. 안넣어주어도 된다.
  DocumentReference? reference;

  UserModel({
    required this.userKey,
    required this.phoneNumber,
    required this.address,
    required this.lat,
    required this.lon,
    required this.geoFirePoint,
    required this.createdDate,
    this.reference,
  });

  UserModel.fromJson(Map<String, dynamic> json, this.userKey, this.reference) {
    userKey = json[DOC_USERKEY];
    phoneNumber = json[DOC_PHONENUMBER];
    address = json[DOC_ADDRESS];
    lat = json[DOC_LAT];
    lon = json[DOC_LON];
    geoFirePoint = GeoFirePoint((json[DOC_GEOFIREPOINT][DOC_GEOPOINT]).latitude,
        (json[DOC_GEOFIREPOINT][DOC_GEOPOINT]).longitude);
    createdDate = json[DOC_CREATEDDATE] == null
        ? DateTime.now().toUtc()
        : (json[DOC_CREATEDDATE] as Timestamp).toDate();
  }

// fromSnapshot 함수 부분이 가장큰 차이나는 부분임 
// fromSnapshot 은 전달받은 인자를 fromJson 으로 전달한다.
// 전달하는 방법은 일반 함수처럼 {} 안에 넣는 방법도 있고,
// : this.fromJson() 방식으로 전달 가능하다, 검색 키워드 - '이니셜라이져'
  UserModel.fromSnapshot(DocumentSnapshot<Map<String, dynamic>> snapshot)
      : this.fromJson(
          snapshot.data()!,
          snapshot.id,
          snapshot.reference,
        );

  Map<String, dynamic> toJson() {
    final map = <String, dynamic>{};
    map[DOC_USERKEY] = userKey;
    map[DOC_PHONENUMBER] = phoneNumber;
    map[DOC_ADDRESS] = address;
    map[DOC_LAT] = lat;
    map[DOC_LON] = lon;
    map[DOC_GEOFIREPOINT] = geoFirePoint.data;
    map[DOC_CREATEDDATE] = createdDate;
    return map;
  }

  @override
  String toString() {
    return 'UserModel {userKey: $userKey, phoneNumber: $phoneNumber, address: $address, lat: $lat, lon: $lon, geoFirePoint: ${geoFirePoint.data['geohash'].toString()}/${geoFirePoint.latitude}/${geoFirePoint.longitude}, createdDate: $createdDate, reference: ${reference.toString()}}';
  }
}

// To parse this JSON data, do
//
//     final userModel1 = userModel1FromJson(jsonString);

// UserModel1 userModel1FromJson(String str) => UserModel1.fromJson(json.decode(str));
// String userModel1ToJson(UserModel1 data) => json.encode(data.toJson());


// 사이트를 이용한 모델링, 일부분은 직접 수정함
class UserModel1 {
  String userKey;
  String phoneNumber;
  String address;
  num lat;
  num lon;
  GeoFirePoint geoFirePoint;
  DateTime createdDate;

  // firestore 에서 데이터를 가져요거나, document 데이터를 가져오는 경우라면
  // DocumentReference 를 넣어줄수 있다. 안넣어주어도 된다.
  DocumentReference? reference;

  UserModel1({
    required this.userKey,
    required this.phoneNumber,
    required this.address,
    required this.lat,
    required this.lon,
    required this.geoFirePoint,
    required this.createdDate,
    this.reference,
  });

  // reference 는 별도로 전달할 예정,
  factory UserModel1.fromJson(Map<String, dynamic> json) => UserModel1(
        userKey: json[DOC_USERKEY],
        phoneNumber: json[DOC_PHONENUMBER],
        address: json[DOC_ADDRESS],
        lat: json[DOC_LAT],
        lon: json[DOC_LON],
        geoFirePoint: GeoFirePoint((json[DOC_GEOFIREPOINT][DOC_GEOPOINT]).latitude,
            (json[DOC_GEOFIREPOINT][DOC_GEOPOINT]).longitude),
        createdDate: json[DOC_CREATEDDATE] == null
            ? DateTime.now().toUtc()
            : (json[DOC_CREATEDDATE] as Timestamp).toDate(),
      );

  Map<String, dynamic> toJson() => {
        DOC_USERKEY: userKey,
        DOC_PHONENUMBER: phoneNumber,
        DOC_ADDRESS: address,
        DOC_LAT: lat,
        DOC_LON: lon,
        DOC_GEOFIREPOINT: geoFirePoint.data,
        DOC_CREATEDDATE: createdDate,
      };

  @override
  String toString() {
    return 'UserModel1 {userKey: $userKey, phoneNumber: $phoneNumber, address: $address, lat: $lat, lon: $lon, geoFirePoint: ${geoFirePoint.data['geohash'].toString()}/${geoFirePoint.latitude}/${geoFirePoint.longitude}, createdDate: $createdDate, reference: ${reference.toString()}}';
  }

}

/* 모델링 샘플 데이터
{
  "userKey": "userKey",
  "phoneNumber": "phoneNumber",
  "address": "address",
  "lat": 123,
  "lon": 123,
  "geoFirePoint": "geoFirePoint",
  "createdDate": "createdDate",
  "reference": "reference"
}
*/