inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

173만명의 커뮤니티!! 함께 토론해봐요.

서버사이드 렌더링을 할 때, 서버는 어디에 있는 건가요?

해결됨

Next.js 시작하기(feat. 지도 서비스 개발)

선생님, 안녕하세요. 너무 기초적인 질문일 수 있지만, 갑자기 궁금해져서 질문드립니다. 서버사이드 렌더링의 경우, 서버에서 pre-render된 코드를 만들어서 보내주고, 클라이언트에서 hydrate를 해서 페이지를 만든다고 알고 있습니다. 클라이언트 사이드 렌더링의 경우는 html코드와 js코드를 함께 보내서, 클라이언트에서 페이지를 만들구요. 서버사이드 렌더링을 할 때, pre-render된 코드를 만드는 서버는 각 클라이언트들의 컴퓨팅 자원을 사용하는 건지(클라이언트의 컴퓨터에서 만드는 건지), 아니면 배포하는 중앙(?)서버(aws ec2 또는 이 강의에서 처럼 vercel)의 컴퓨팅 자원을 사용하는 건지(서버에서 만드는 건지) 궁금합니다. 클라이언트 측에서 다 계산을 한다고 하면, 중앙(?)서버의 부담이 적을테지만, 중앙(?)서버에서 한다고 하면, 부담이 갈 수 있을 것 같아서요. 최근 next.js 14버전이 되면서 디비와 직접 통신하는 등 기능이 많이 생겼는데, 이 통신하는 등의 역할은 client side가 아닌 server side에서만 가능하더라구요. 그래서 server side라는 게 중앙서버 하나에만 있다면, 계산이 오래걸린다거나 트래픽이 늘어나거나 한다면 다른 사용자들에게도 영향을 끼치지 않을까 궁금했습니다.(자동 확장이 되지 않을때) 또, 이런식으로 간다면 따로 백엔드 서버가 필요없게 될 수도 있겠다라고도 생각해봤는데, 어떻게 보고계시는지도 궁금합니다.

  • seo
  • next.js
  • vercel
  • csr
  • ssg
  • ssr
google_user 댓글 2 좋아요 1 조회수 1214

미세먼지 데이터를 불러오는 과정에서 이슈가 있어 질문 드립니다.

해결됨

[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

안녕하세요. stat_repository.dart 파일 내부에서 API를 불러오는 과정에 이슈가 있어 질문 드립니다. import 'package:dio/dio.dart'; import 'package:dusty_dust/const/data.dart'; import 'package:dusty_dust/model/stat_model.dart'; class StatRepository { static Future<List<StatModel>> fetchData() async { // final response = await Dio().get( // 'http://apis.data.go.kr/B552584/ArpltnStatsSvc/getCtprvnMesureLIst', // queryParameters: { // 'serviceKey': serviceKey, // 'returnType': 'json', // 'numOfRows': 30, // 'pageNo': 1, // 'itemCode': 'PM10', // 'dataGubun': 'HOUR', // 'searchCondition': 'WEEK', // }, // ); final response = await Dio().get( 'http://apis.data.go.kr/B552584/ArpltnStatsSvc/getCtprvnMesureLIst' '?serviceKey=$serviceKey' '&returnType=json' '&numOfRows=30' '&pageNo=1' '&itemCode=PM10' '&dataGubun=HOUR' '&searchCondition=WEEK', ); return response.data['response']['body']['items'] .map<StatModel>( (item) => StatModel.fromJson(json: item), ) .toList(); } } 위 코드에서 주석을 처리한 부분대로 API를 호출하면(기존 강의 내용) 다음과 같은 에러가(서비스키가 등록되지 않았다는 내용) 나오고 <OpenAPI_ServiceResponse> <cmmMsgHeader> <errMsg>SERVICE ERROR</errMsg> <returnAuthMsg>SERVICE_KEY_IS_NOT_REGISTERED_ERROR</returnAuthMsg> <returnReasonCode>30</returnReasonCode> </cmmMsgHeader> </OpenAPI_ServiceResponse> 위 코드에서 엔드포인트 부분에 직접 파라미터를 적으면 정상적으로 데이터가 출력됩니다. 관련 이슈들을 구글링 해보니 serviceKey 를 받아오는 과정에서 인코딩 과정이 별도로 필요하다는데 만약 내부 설정을 변경 한다면 어떻게 해야 할까요?

  • flutter
  • 클론코딩
MinwooNa 댓글 2 좋아요 0 조회수 370

비디오 플레이어에서 onSliderChange에 대해 질문있습니다~

해결됨

[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

안녕하세요. 비디오 플레이어 강의를 모두 듣고 소스를 복습하고 있습니다. 복습을 하면서 한가지 아리송한게 있어서 질문드립니다. 여기 onSliderChange의 val은 _Bottom으로 따로 빼서 구현한 함수에서 value인 currentPosition.inSeconds.toDouble()를 받는건가요? print로 찍어가며 확인한 결과 맞는거 같긴한데 아리송해서 질문드립니다~ void onSliderChange(double val) { videoController!.seekTo( Duration( seconds: val.toInt(), ), ); } Expanded( child: Slider( value: currentPosition.inSeconds.toDouble(), onChanged: onSliderChange, max: maxPosition.inSeconds.toDouble(), min: 0, ), ),

  • flutter
  • 클론코딩
gijung.lee 댓글 1 좋아요 0 조회수 351

typedef를 사용하는이유?

해결됨

[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

이전 강의까지는 상위 class에 method를 생성해서 onTap() 함수를 넘겨줬는데 이번엔 전역으로 typedef로 선언한 이유가 있을까요? typedef ColorIdSetter = void Function(int id); class _ColorPicker extends StatelessWidget { const _ColorPicker({ super.key, required this.colors, required this.selectedColorId, required this.colorIdSetter, }); final List<CategoryColor> colors; final int selectedColorId; final ColorIdSetter colorIdSetter; @override Widget build(BuildContext context) { return Wrap( runSpacing: 10, spacing: 8, children: colors .map( (e) => GestureDetector( onTap: () { colorIdSetter(e.id); }, child: renderColor(e, selectedColorId == e.id), ), ) .toList(), ); }

  • flutter
  • 클론코딩
정중한 가자미 댓글 1 좋아요 0 조회수 540

설치했으나 인지를 못하는듯합니다

미해결

[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

- 안드로이드 스튜디오 설치 했으나 not install cocoapads 또한 영상대로 진행했고 java는 자체적으로 설치한건 없으나 안드로이드 스튜디오에 내장된걸로 알고있습니다 개인적으로 안드로이드 스튜디오가 설치가 안되있는걸로 나오니 java도 인지를 못하는가 싶기도하고 xcode 시뮬레이터는 안켜지네요 ㅜ 삽질을 계속 하고있는거같아 사진찍어 문의드립니다 사진상 보시면 뒤에 어두운 계열로 켜져있는데 그게 안드로이드 스튜디오로 이미 설치가 되어있습니다 해결책좀 부탁드림다 ㅜ

  • flutter
  • 클론코딩
염호경(hokki) 댓글 3 좋아요 0 조회수 374

PatchMeBasketDto 서버 에러 급합니다.

해결됨

[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!

안녕하세요. 섹션 16 -> Postman API 테스트 부분을 듣고 있는 수강생입니다. 하나씩 강의 영상대로 따라하면서 공부하고있습니다. 로그인 요청을 보내서 로그인 토큰을 받고 GET / restaurant 으로 레스토랑 리스트 받아오고 받아온 레스토랑 id를 기반으로 restaurant/:rid 에 rid 키로 상세 페이지를 요청하였습니다. 그 후 user/me/basket의 productId 상세페이지에서 나온 id를 입력했는데 서버에서 아래와 같은 오류가 나옵니다. 강사님의 빠른 답변 기다리겠습니다. 좋은 강의 감사합니다. ==== 포스트맨 에러 { "statusCode": 500, "message": "Internal server error" } ==== NextJS 에러 {} PatchMeBasketDto {} [Nest] 6648 - 2023. 11. 21. 오후 4:21:06 ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'map') TypeError: Cannot read properties of undefined (reading 'map') at UserService._mapBasketDtoToProduct (D:\FlutterProject\restapi\src\user\user.service.ts:74:21) at UserService.addToBasket (D:\FlutterProject\restapi\src\user\user.service.ts:66:24) at UserController.patchMeBasket (D:\FlutterProject\restapi\src\user\user.controller.ts:87:29) at D:\FlutterProject\restapi\node_modules\@nestjs\core\router\router-execution-context.js:38:29 ==== 단계별 스크린샷 1. 레스토랑 리스트 요청 2. 상세 레스토랑 정보 요청 3. PATCH 장바구니 요청 4. 서버 에러

  • flutter
  • 하이브리드-앱
rlagywhd019 댓글 1 좋아요 1 조회수 365

안녕하세요 제너릭 관련하여 질문이 있습니다.

미해결

[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!

안녕하세요. 해당 강의에 질문이 있어서 글을 남깁니다. 강의에 소개된대로 itemBuilder에 RestaurantModel 제너릭을 제공해준 경우 return PaginationListView( provider: restaurantProvider, itemBuilder: <RestaurantModel>(context, index, model) { return GestureDetector( onTap: () { Navigator.of(context).push(MaterialPageRoute( builder: (_) => RestaurantDetailScreen( id: model.id, ), )); }, child: RestaurantCard.fromModel(model: model), ); }, ); PaginationListView에 제너릭을 제공한 경우 return PaginationListView<RestaurantModel>( provider: restaurantProvider, itemBuilder: (context, index, model) { return GestureDetector( onTap: () { Navigator.of(context).push(MaterialPageRoute( builder: (_) => RestaurantDetailScreen( id: model.id, ), )); }, child: RestaurantCard.fromModel(model: model), ); }, ); 위 두가지 경우 중에 PaginationListView 소스를 확인하면 2번 항목이 맞는거 같은데 작동은 1번에서만 가능합니다. typedef PaginaitonWidgetBuilder<T extends IModelWithId> = Widget Function( BuildContext context, int index, T model, ); class PaginationListView<T extends IModelWithId> extends ConsumerStatefulWidget { final StateNotifierProvider<PaginationProvider, CursorPaginationBase> provider; final PaginaitonWidgetBuilder<T> itemBuilder; const PaginationListView({ super.key, required this.provider, required this.itemBuilder, }); @override ConsumerState<PaginationListView> createState() => _PaginationListViewState<T>(); } 제가 생각한 해석방식은 이렇습니다. PaginationListView 생성 시 ImodelWithId를 extend 한T 타입을 제너릭으로 받습니다. 따라서 itemBuilder가 아닌 PaginationListView<RestaurantModel>과 같이 제너릭을 제공한 경우, 해당 타입을 PaginationWidgetBuilder에 매핑 됩니다. 위 해석방식에서 제가 틀리게 생각한게 있나요? 에러메시지는 아래와 같습니다. The following _TypeError was thrown building: type '(BuildContext, int, RestaurantModel) => GestureDetector' is not a subtype of type '(BuildContext, int, IModelWithId) => Widget'

  • flutter
  • 하이브리드-앱
엄태호 댓글 1 좋아요 0 조회수 281

결제오류 입니다.

미해결

[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!

코드는 전혀 문제가 없는 것 같은데, 결제창으로 넘어가지를 않습니다. 코드를 보면 만약 resp 일때 OrderDoneScreen으로 넘어가도록 되어있는데, 그 resp 는 await ref.read (orderProvider.notifier).postOrder(); 이라고 했습니다. 그렇다면 이 resp가 이 상태가 아니라는 건데, 이걸 어떻게 확인을 하면 좋을까요? 에러의 이유로는 'type 'Null' is not a subtype of type 'String' in type cast' 라고 나옵니다. 저번에는 재설치 하면 넘어갔었는데, 이번에는 아무리 모든 코드를 검사해봐도 이유를 모르겠습니다 ㅠ SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () async { final resp = await ref.read(orderProvider.notifier).postOrder(); if (resp) { context.goNamed(OrderDoneScreen.routeName); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( '결제 실패!', ), ), ); }

  • flutter
  • 하이브리드-앱
김지현 댓글 2 좋아요 0 조회수 372

GoRoute List 위치 질문입니다.

미해결

[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!

List<GoRoute> 를 go_router.dart가 아닌 auth_provider.dart에 넣은 이유가 있을까요? 작동은 잘 되지만 코드가 헷갈릴 때가 있어 질문드립니다. 라우터 관련 코드들은 go_router에 넣으면 가독성이 더 편해질 것 같은데 auth_provider에 넣은 이유가 있을까요??

  • flutter
  • 하이브리드-앱
김상호 댓글 1 좋아요 0 조회수 476

인코딩과 컬럼선택기준

해결됨

[퇴근후딴짓] 빅데이터 분석기사 실기 (작업형1,2,3)

인코딩을 할때 선생님이 어쩔때는 원핫인코딩을 하시고 어쩔때는 레이블인코딩을 하시던데 그 인코딩을 정하시는 기준을 잘 모르겠습니다! 인코딩을 정하실때 그 경우에 대해서 자세히 알려주시면 감사하겠습니다 그리고 인코딩을 할때 컬럼도 몇개 정하셔서 하시던데 그 컬럼고르는 기준도 잘 모르겠습니다 그 기준에 대해서도 선택하는 방법을 알려주시면 감사하겠습니다 ㅠㅠ

  • python
  • 머신러닝
  • 빅데이터
  • pandas
  • 빅데이터분석기사
jms717958 댓글 1 좋아요 0 조회수 375

플러터 바탕화면 빠진후 앱 진행시

해결됨

[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter

안녕하세요 . 섹션7의 검색 라우터를 진행하다가 우연히 바탕화면에 들어갔다가 앱마크를 재생버튼이 아닌 앱 마크를 클릭을 했더니 splash 화면에서 로딩중으로만 계속 되어있고 print를 찍었더니 아예 App()에 있는 Gorouter 자체를 타지를 않는 현상이 생기고 있습니다. 혹시 바탕화면 갔다가 다시 홈페이지 화면으로 들어가려고 하는데 방법이 있을까 해서 글을 작성드렸습니다. 감사합니다 ㅠㅠ

  • flutter
  • firebase
  • bloc
열심히 댓글 6 좋아요 1 조회수 914

플러터 로컬 푸시 아이콘 질문있습니다.

미해결

import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:permission_handler/permission_handler.dart'; class FlutterLocalNotification { FlutterLocalNotification._(); static FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); static init() async { AndroidInitializationSettings androidInitializationSettings = const AndroidInitializationSettings('mipmap/ic_launcher'); InitializationSettings initializationSettings = InitializationSettings( android: androidInitializationSettings); await flutterLocalNotificationsPlugin.initialize(initializationSettings); } static Future<void> showNotification() async { const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails('channel id', 'channel name', channelDescription: 'channel description', importance: Importance.max, priority: Priority.max, showWhen: false); const NotificationDetails notificationDetails = NotificationDetails( android: androidNotificationDetails, ); await flutterLocalNotificationsPlugin.show( 0, 'test title', 'test body', notificationDetails); //await flutterLocalNotificationsPlugin.cancel(0); 아이디가 0인 알람 삭제 } static Future<PermissionStatus> requestNotificationPermissions() async { final status = await Permission.notification.request(); return status; } } 다른 사람들 보면 아이콘도 같이 나오는데 저는 아이콘이 나오지 않아서 이렇게 질문드려요 어디가 이상한지 모르겠습니다.

  • flutter
  • 플러터
정충효 댓글 1 좋아요 0 조회수 556

캘린더 생성 및 수정 관련 기능 관련 질문이 있습니다.

해결됨

[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

좋은 강의 올려주셔서 감사합니다! 다름이 아니라 스케쥴 생성 및 수정하는 과정에서 startTime 이 endTime 보다 클 경우 create나 update를 방지하는 기능을 추가 하고 싶습니다. 클라이언트에서는( schedule_bottom_sheet.dart ) onSavePressed 에서 검증처리를 추가하면 될거 같은데, 만약 서버에서도( drift_database.dart ) 이중으로 create나 update가 되는걸 방지할려면은 createSchedule 및 updateScheduleById 내부 로직에서 검증 처리를 별도로 하면 되는지 궁금합니다.

  • flutter
  • 클론코딩
MinwooNa 댓글 1 좋아요 0 조회수 267

구글 플러터 지도

미해결

[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

안녕하세요 강의영상이나 책에는 아래 설치하는 내용은 없는것 같은데.. 안해도 무방한건지요? (아래 링크에는 yaml에 버전 추가하는 것은 없던데 혹시 그걸로 대체되는 것인지..) 제가 google_maps_cluster_manager: ^3.0.0+1 를 이용하려고 하는데 혹시 영향이 있을까봐 여쭙니다 :) https://developers.google.com/maps/flutter-package/config?hl=ko#android 이 작업을 간소화하려면 Android용 Secrets Gradle 플러그인 을 사용하는 것이 좋습니다. 플러그인을 설치하여 API 키를 저장하는 방법은 다음과 같습니다. Android 스튜디오에서 프로젝트 수준 build.gradle 파일을 열고 다음 코드를 buildscript 아래 dependencies 요소에 추가합니다. plugins { // ... id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1' apply false } 그런 다음 모듈 수준 build.gradle 파일을 열고 plugins 요소에 다음 코드를 추가합니다. id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' 파일을 저장하고 프로젝트를 Gradle과 동기화 합니다. 프로젝트 수준 디렉터리에서 local.properties 를 열고 다음 코드를 추가합니다. YOUR_API_KEY 를 API 키로 변경합니다. MAPS_API_KEY= YOUR_API_KEY

  • flutter
  • 클론코딩
박정인 댓글 1 좋아요 0 조회수 319

작업형2에서 언제는 분류모델을 써야하고 언제는 회귀모델을 써야할까요?!

해결됨

[퇴근후딴짓] 빅데이터 분석기사 실기 (작업형1,2,3)

보통 작업형2에서는 예측값을 물어보는 문제가 나오던데요. 문제가 나올때 어느문제는 분류모델을, 어느문제는 회귀모델을 사용해야하는지 궁금합니다. 지금까지 강의+기출문제를 보면서는 분류/회귀를 결정하는 부분이 평가 모델을 통해 진행된다는 느낌을 받았는데요. 1) roc_auc_score, accuracy_score 이 평가모델로 쓰일 경우, 분류형 모델 사용(Classifier) 2) rmse, mean_squared_error 이 평가모델로 쓰일 경우, 회귀모델 사용(Regressor) 이렇게 생각하면서 작업형2를 접근하는게 맞는지 궁금합니다.

  • python
  • 머신러닝
  • 빅데이터
  • pandas
  • 빅데이터분석기사
hello4298 댓글 1 좋아요 0 조회수 386

ShellRoute 실행 결과가 이상합니다 ..

해결됨

[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!

선생님이랑 코드 똑같이 쓰고 라우트 위치도 맞는데 NestedScreen 가보면 이렇게 나옵니다. 아래는 더러울 수도 있지만 코드 전체 첨부합니다. class NestedScreen extends StatelessWidget { final Widget child; NestedScreen({super.key, required this.child}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(GoRouterState.of(context).matchedLocation), ), body: child, bottomNavigationBar: BottomNavigationBar( items: [ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'home', ), BottomNavigationBarItem( icon: Icon(Icons.person), label: 'person', ), BottomNavigationBarItem( icon: Icon(Icons.notifications), label: 'notifications', ), ], ), ); } } // router.dart ShellRoute( builder: (context, state, child) { return NestedScreen(child: child); }, routes: [ GoRoute( path: 'nested/a', builder: (_, state) => NestedChildScreen(routeName: '/nested/a'), ), GoRoute( path: 'nested/b', builder: (_, state) => NestedChildScreen(routeName: '/nested/b'), ), GoRoute( path: 'nested/c', builder: (_, state) => NestedChildScreen(routeName: '/nested/c'), ), ], ),

  • flutter
  • 하이브리드-앱
김상호 댓글 1 좋아요 0 조회수 591

접속중인 사용자의 정보 가져오기 강의 관련 질문

해결됨

Flutter로 SNS 앱 만들기

안녕하세요. 강의 잘 듣고 있습니다. 접속중인 사용자의 정보 가져오기 강의 관련 질문 있습니다. 아래와 같이 영상과 같이 코딩했는데 빨간 줄이 지워지지 않습니다. Future<UserModel> 로 함수 정의를 했는데 빨간 줄이 지워지지 않습니다. 무슨 문제인지 모르겠습니다. 바쁘신데 질문 읽어주셔서 감사합니다.

  • flutter
  • android
  • firebase
  • dart
강민석 댓글 2 좋아요 0 조회수 397

그냥 질문입니다.

미해결

[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

데이터 관리를 SQLite와 Firebase와 무슨 차이점 인가요? 제가 다른 강의를 보다가 넘어와서요. firebase가 익숙해서 드리는 질문입니다. 또 어느 문제가 발생합니까?

  • flutter
  • 클론코딩
vadain2000 댓글 1 좋아요 0 조회수 280

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

해결됨

Flutter로 SNS 앱 만들기

안녕하세요. 강의 잘 듣고 있습니다. 사용자 정보, 게시글 정보를 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 조회수 379

위젯과 클래스

미해결

[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

Boxdecoration()은 위젯이라고 볼 수 없는건가요? 볼 수 있는거 아닌가요?제가 이해하기로는 위젯과 위젯이 아닌 클래스의 차이로는위젯은 컨스트럭터 자체로 역할을 할 수 있고 위젯이 아닌 클래스는 컨스트럭터 자로 역할을 할 수는 없고, 그 컨스트럭터로 인스턴스를 만들고 그 인스턴스로 메서드나 멤버변수 이용라는걸로 이해하고 있습니다. 위 내용에 따르면 Boxdecoration()도 위젯 아닌가요?위젯과 위젯이 아닌 클래스를 나누는 명확한 기준이 있나오?

  • flutter
  • 클론코딩
강원빈 댓글 1 좋아요 0 조회수 223

인기 태그

인프런 TOP Writers

주간 인기글