[๐งโ๐ป] Keymory ๊ฐ๋ฐ ์ผ์ง #7: FleatherViewer ์ด์ ํด๊ฒฐ, HomeFeedPage Unexpected null value ์ด์ ํด๊ฒฐ
โจ GPT์ ์์ฝ ใ
FleatherViewer์ ์ ๋ฐ์ดํธ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ , HomeFeedPage์ ํํฐ๋ง ๋ฐฉ์ ๊ฐ์ ์ ํตํด ์ด์ ํด๊ฒฐ ๋ฐ ์ฑ๋ฅ ์ต์ ํ ์๋ฃ. ๋๋ถ์ Query ํํฐ ๋์ Conditional Visibility๋ฅผ ํ์ฉํ๋ ๊ฒ์ด ํจ๊ณผ์ ์์ ๋ฐฐ์ ์.
๐ป ๊ฐ๋ฐ ์ผ์ง
โฐ ์ค๋ ํ ์ผ
- โ
(์ด์) HomeFeedPage - FeedCardDiary: ListView์์ ๋ ์ง๋ฅผ ๋ณ๊ฒฝํด๋, ์ค์ง FleatherViewerWidget๋ง ๊ฐ์ด ๋ณํ์ง ์์.
- ์๋ง Widget์ initialDeltaJson ๊ฐ์ด Diary Document ๋ณ๊ฒฝ ์๋ง๋ค ์ ๋ฐ์ดํธ๋์ง ์๋ ๊ฒ ๊ฐ์.
-
o1์๊ฒ ๋ฌผ์ด๋ณด์๋ง์ ํ ๋ฐฉ์ ํด๊ฒฐ.
/// didUpdateWidget: /// - ๋์ผ ์์ ฏ ํธ๋ฆฌ์์ ๋จ์ํ ํ๋ผ๋ฏธํฐ๋ง ๋ฐ๋ ๊ฒฝ์ฐ, Flutter๊ฐ ๊ธฐ์กด State๋ฅผ ์ฌ์ฌ์ฉ. /// - ์ด๋ ์ widget ์์ฑ๊ณผ ๊ธฐ์กด widget ์์ฑ์ ๋น๊ตํ์ฌ ํ์ํ ๋ก์ง์ ์ํํ ์ ์์. @override void didUpdateWidget(covariant FleatherViewerWidget oldWidget) { super.didUpdateWidget(oldWidget); // 1) ์ด์ JSON๊ณผ ์๋ก์ด JSON์ด ๋ค๋ฅด๋ฉด if (oldWidget.initialDeltaJson != widget.initialDeltaJson) { // 2) FleatherController๋ฅผ ์๋ก ์์ฑ _controller?.dispose(); _controller = _createControllerFromDeltaJson(widget.initialDeltaJson); // 3) UI ๊ฐฑ์ setState(() {}); } } /// Delta JSON ๋ฌธ์์ด์ FleatherController๋ก ๋ง๋๋ ํฌํผ ํจ์ FleatherController _createControllerFromDeltaJson(String jsonString) { ParchmentDocument doc; try { final decoded = jsonDecode(jsonString); doc = ParchmentDocument.fromJson(decoded); } catch (e) { // ๋ณต์ ์คํจ ์, ์ผ๋ฐ ํ ์คํธ ์ฒ๋ฆฌ doc = ParchmentDocument.fromDelta( Delta()..insert(_ensureEndsWithNewline(jsonString)), ); } return FleatherController(document: doc); }
- โ
(์ด์) HomeFeedPage: On page load์ Unexpected Null Value ์ ๊น ๋ด๋ค ์ฌ๋ผ์ง.
- HomeFeedPage์ Listview์ ๊ฑธ๋ฆฐ
๋ ์ง ํํฐ๋ง
์ด ๋ฌธ์ ์ธ ๊ฒ์ผ๋ก ํ์ธ. - โListViewโ์ โBackend Queryโ ์ต์
์์ Filter On Null Values๋ฅผ ์ผ๋ดค์.
- Filter On Null Values: By default, if the value of any filter is null, the query will ignore the filter for that field. Checking this will instead keep null filters.
- Backend Query - Query Collection ์์ ์๋ 1 (์คํจ)
- Filter On Null Values: ON
- Filter 1:
created_time
,Equal To
,getFirstTimeOfTheDay
- Filter 2:
created_time
,Less Than
,getFirstTimeOfNextDay
- Order by:
created_time
,Decreasing
- Backend Query ์ค์ ์๋ฃ ๋ถ๊ฐ
- ์๋ฌ ๋ฉ์์ง: You canโt order your query by a field used in a filter using
==
orin
.
- ์๋ฌ ๋ฉ์์ง: You canโt order your query by a field used in a filter using
- Backend Query - Query Collection ์์ ์๋ 2 (์คํจ)
- Filter On Null Values: ON
- Filter 1:
created_time
,Greater Than or Equal To
,getFirstTimeOfTheDay
- Filter 2:
created_time
,Less Than
,getFirstTimeOfNextDay
- Order by:
created_time
,Decreasing
- Backend Query ์ค์ ์๋ฃ ๊ฐ๋ฅ
-
๋๋ฒ๊น ๋ชจ๋ ์ง์ ์ ์๋์ ์๋ฌ๊ฐ ๋จ๊ณ ํ์ด์ง๊ฐ ์์ฑ ์ ๋จ.
Assertion failed: file:/// opt/ - pub-cache/hosted/pub.dev/ cloud_firestore-5.5.0/lib/src/ query dart: 650:9 conditions .where ((List<dynamic> item) => equality.equals(condition, item)) .isEmpty "Condition [FieldPath([created_time]), !=, null] already exists in this query." The relevant error-causing widget was: HomeFeedWidget
- Backend Query - Query Collection ์์ ์๋ 3 (์คํจ)
- Filter On Null Values: ON
- Filter 1:
created_time
,Greater Than
,getLastTimeOfPrevDay
- Filter 2:
created_time
,Less Than
,getFirstTimeOfNextDay
- Order by:
created_time
,Decreasing
- Backend Query ์ค์ ์๋ฃ ๊ฐ๋ฅ
-
๋๋ฒ๊น ๋ชจ๋ ์ง์ ์ ์๋์ ์๋ฌ๊ฐ ๋จ๊ณ ํ์ด์ง๊ฐ ์์ฑ ์ ๋จ.
Assertion failed: file:/// opt/ - pub-cache/hosted/pub.dev/ cloud_firestore-5.5.0/lib/src/ query dart: 650:9 conditions .where ((List<dynamic> item) => equality.equals(condition, item)) .isEmpty "Condition [FieldPath([created_time]), !=, null] already exists in this query." The relevant error-causing widget was: HomeFeedWidget
- Backend Query - Query Collection ์์ ์๋ 4 (์คํจ)
- Filter On Null Values: OFF
- Filter 1:
created_time
,Greater Than
,getLastTimeOfPrevDay
- Filter 2:
created_time
,Less Than
,getFirstTimeOfNextDay
- Order by:
created_time
,Decreasing
- Backend Query ์ค์ ์๋ฃ ๊ฐ๋ฅ
-
๋๋ฒ๊น ๋ชจ๋ ์ง์ ์ ์๋์ ์๋ฌ๊ฐ ์ ๊น ๋ด๋ค ์ฌ๋ผ์ง.
Unexpected Null value. The relevant error-causing widget was: HomeFeedWidget
- (o1 ์๊ฒ ์ง๋ฌธ) ์ Unexpected Null Value๊ฐ ์ ๊น ๋จ๋ ๊ฑธ๊น?
- FlutterFlow(ํน์ ๋ด๋ถ ์ฝ๋)์์ ํ์ด์ง ์ด๊ธฐ ๋ก๋ฉ ์์ ์ getLastTimeOfPrevDay()๋ getFirstTimeOfNextDay() ๋ฑ์ด null์ ๋ฐํํ๊ณ ์์ ๊ฐ๋ฅ์ฑ์ด ์ปค. (์: date๊ฐ ์์ง ์ด๊ธฐํ๊ฐ ์ ๋๋ค๋ ์งโฆ)
- Filter On Null Values๊ฐ ์ผ์ ธ ์์ผ๋ฉด, ๋ด๋ถ์ ์ผ๋ก != null ๊ฐ์ ์กฐ๊ฑด์ ๋ฐ๋ก ์ถ๊ฐํ๊ฒ ๋๋๋ฐ, ์ด๊ฒ ๋ก๋ฉ ์๊ฐ์ null ๊ฐ์ด ๋ค์ด๊ฐ๋ฉด์ ์ถฉ๋์ด ๋ ์ ์์ด.
- ๊ทธ๋์ โ์ ๊น null ์๋ฌ ๋์ฐ๊ณ -> ์ค์ ๊ฐ์ผ๋ก ๋์ฒด๋ ๋ค -> ๋ก๋ฉ์ด ๋๋๋ฉด ์ฌ๋ผ์ง๋โ ํ์์ด ๋ฐ์ํ๋ ๊ฑฐ์ง.
- Backend Query - Query Collection ์์ ์๋ 5 (์ฑ๊ณต!)
- Filter On Null Values: OFF
- Order by:
created_time
,Decreasing
- Component Widget Conditional Visibility ์ค์
- Filter 1:
created_time
,Greater Than
,getLastTimeOfPrevDay
- Filter 2:
created_time
,Less Than
,getFirstTimeOfNextDay
- Filter 1:
- ๊ฒ๋ค๊ฐ ๋ค์ผ๋ก, ListView ๋ก๋ฉ ๋ (Latency)์ด ์ฌ๋ผ์ก์. Query์ Filter 2๊ฐ์ Order๋ฅผ ๋์์ ์คฌ๊ธฐ์ ๋ง์ ์๊ฐ์ด ์์๋ ๊ฒ ๊ฐ์.
- ๐ก ๋ฐฐ์ด ์
- Backend Query ์ฌ์ฉํ ๋๋ ํํฐ ์ฌ์ฉ์ ์ต๋ํ ๋ฐฐ์ ํ๊ณ , Conditional Visibility๋ก ์ปจํธ๋กค ํ๋ ๊ฒ ์ข๋ค.
- ์ด๊ฑฐ ์ด๋ฐ์ ๋ฉํ ๋๊ป ์ฌ์ญค๋ด์ ๋ต๋ณ ๋ฐ์๋ ๊ฑด์ธ๋ฐ, ๋จธ๋ฆฌ๋ก๋ง ๋์ถฉ ์ดํดํ๊ณ ๋์ด๊ฐ์ ๊ฒฐ๊ตญ ์์ด๋ฒ๋ ธ๋ ๊ฒ ๊ฐ๋ค. ์ง์ ๊ณ ์ํด๋ณด๊ณ ๋๋๊น ์ด์ ์์ผ ํ์คํ ๊นจ๋ซ๊ฒ ๋์์.
- HomeFeedPage์ Listview์ ๊ฑธ๋ฆฐ
- โ
(์ด์) DiaryPage: ๋ ์ง๊ฐ ์ค๋๋ก๋ง ์ ์ฅ๋จ
- DiaryPage - dateFocused ํ๋ผ๋ฏธํฐ ์์ฑ
- HomeFeedPage์ dateToShow๊ฐ์ dateFocused ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ.
๐ฏ ํ ์ผ์ ๋ํ ์์ฝ
FleatherViewer ์ ๋ฐ์ดํธ ๋ฌธ์ ํด๊ฒฐ
- didUpdateWidget์ ํ์ฉํด FleatherViewer๊ฐ Diary Document ๋ณ๊ฒฝ ์๋ง๋ค ์ ์์ ์ผ๋ก ์ ๋ฐ์ดํธ๋๋๋ก ์์ . HomeFeedPage ํํฐ ์ต์ ํ
Backend Query์ ํํฐ๋ง ๋ฐฉ์ ๋์ Conditional Visibility๋ฅผ ํ์ฉํด ์ฑ๋ฅ ๊ฐ์ .
- Query ํํฐ๋ง์ ์ต์ํํจ์ผ๋ก์จ ๋ก๋ฉ ์๋ ํฅ์.
DiaryPage ๋ ์ง ์ ์ฅ ์ค๋ฅ ์์
- HomeFeedPage์์ DiaryPage๋ก dateFocused ๊ฐ์ ์ ๋ฌํ์ฌ, ์๋ก์ด ์ผ๊ธฐ๊ฐ ์์ฑ๋ ๋ ์ ํ๋ ๋ ์ง๊ฐ ๋ฐ์๋๋๋ก ๊ฐ์ .
๐ฏ ์ถํ์ ํ ์ผ
์์ธํ ๋ณด๋ ค๋ฉด ํด๋ฆญ
- โ (์ด์) DiaryPage: ๋งํฌ๋ค์ด ๋ทฐ์ด ํ์ฉ (์ค๋ฒํ๋ก์ฐ ๋ฐฉ์ง: Container Height)
- โ (์ด์) HomeFeedPage - FeedCardDiary: AI Comment ์บ๋ฆญํฐ ์ด๋ฏธ์ง ์๋ง๊ฒ ์ ์ฉ
- โ DiaryPage - AI Comment: Save์, ์ฝ๋ฉํธ ์์ฑํ ์บ๋ฆญํฐ Ref๋ Diary์ ์ ์ฅ.
- โ HomeFeedPage - FeedCardDiary - AI Image: Backend Query๋ก ์บ๋ฆญํฐ Doc ๋ถ๋ฌ์์ Image Path ์ง์ .
-
โ DiaryPage: Mood Slider ๊ฐ์ ๋ฐ๋ผ ์ผ๊ตด ํ์ Emoji ๋ณ๊ฒฝ
- โ Chat Page - Create New Chat: ์์คํ
ํ๋กฌํํธ ์ ์ฉํ๊ธฐ
- โถ๏ธ OpenAI API Call ๊ตฌํ: createChatCompletion
- Input: System Prompt(Chat)
- Output: New Chat Message by AI($.choices[0].message.content)
- Additional Actions: Create New Chat, Create New Message
- โถ๏ธ OpenAI API Call ๊ตฌํ: createChatCompletion
- โ DiaryPage - Create New Chat by Diary: ์ผ๊ธฐ์ ๋ด์ฉ์ ๊ธฐ๋ฐ์ผ๋ก, New Chat ์์ฑ
- โ OpenAI API Call ๊ตฌํ: createDiaryComment
- Input: Diary Content, System Prompt(AI Comment)
- Output: AI Comment($.choices[0].message.content)
- โ OpenAI API Call ๊ตฌํ: createDiarySummary
- Input: Diary Content, AI Comment, System Prompt(Diary Summary)
- Output: Diary Summary($.choices[0].message.content)
- โ OpenAI API Call ๊ตฌํ: createChatFromDiary
- Input: Diary Summary, System Prompt(Chat From Diary)
- Output: New Chat Message by AI($.choices[0].message.content)
- Additional Actions: Create New Chat, Create New Message
- โ OpenAI API Call ๊ตฌํ: createDiaryComment
- โ ChatPage - Create New Diary: ๋ํ ๋ด์ฉ์ ๊ธฐ๋ฐ์ผ๋ก, New Diary ์์ฑ
- โ OpenAI API Call ๊ตฌํ: createChatSummary
- Input: Chat Content, System Prompt(Diary From Chat)
- Output: Chat Summary
- โ OpenAI API Call ๊ตฌํ: createChatSummary
- โ ChatPage - Create New Diary: ๋ํ ๋ด์ฉ์ ๊ธฐ๋ฐ์ผ๋ก, New Diary ์์ฑ
- โ OpenAI API Call ๊ตฌํ: createDiaryFromChat
- Input: Chat Summary, System Prompt(Diary From Chat)
- Output: New Diary(Title, Content, Mood score)
- โ OpenAI API Call ๊ตฌํ: createDiaryFromChat
-
โ ChatPage: Go to Linked Diary
- โ HomeFeedPage - flutter_slidable:4.0.0 import ํ ์ ์ฉํ๊ธฐ
-
โ HomeFeedPage: FeedCardDiary์์ ์ข์ฐ slide์ ์ฑํ /ํธ์ง/์ญ์
- โ ChatPage: ์ ์ ๋ํ ์ถ๋ ฅ ๋ด์ฉ์ ์ค๋ฅธ์ชฝ ์ ๋ ฌ
-
โ Chat/Diary: GPT Streaming API
- โ ChatPage - AI ์ ํก ๊ตฌํ (Alarm/Notification)
- ์ฑํ
์์คํ
ํ๋กฌํํธ์ ํต์ฌ์ ๋ฅ๋ํ์ด๋ค.
- ๋ ๋ฆฌ์ผํ๊ฒ ํ๋ ค๋ฉด, create_date of diary/chat ๋ ์ ๋ฌํด์, โ์ด์ โ ๋ฑ ๋ ์ง๋ฅผ ์ธ๊ธํ๋ฉด ์ข์ ๋ฏ.
- Alarm ๊ธฐ๋ฅ ๊ตฌํ ๋ฐฉ๋ฒ ์ฐธ์กฐ
- ์ฑํ
์์คํ
ํ๋กฌํํธ์ ํต์ฌ์ ๋ฅ๋ํ์ด๋ค.
- โ DiaryPage: ์ธ๋ถ ๊ฐ์ ํค์๋ Choice Chips ์ถ๊ฐ ํ DB ์ฐ๋ ์ค์
- โ DiaryPage - AI Comment: Choice chips, mood slider ๋ฑ์ ์
๋ ฅ๊ฐ๋ค์
AI Comment System Prompt
์ ์๋ง๊ฒ ๋ณ๊ฒฝ.- โ **์ด์
์ผ๊ธฐ
๋๋๋ํ ๋ด์ญ
์ ์ฒด (๋๋นต ๊ธฐ์ ๋ถ์ฑ) - โ ์ฌ์ฉ์ ๊ธฐ๋ณธ ์ ๋ณด: ์ด๋ฆ, ์ฑ๋ณ, MBTI, โฆ
- โ ์ธ๋ถ ๊ฐ์ ํค์๋: ์ฆ๊ฑฐ์ด, ์ฌํ, โฆ
- โ ์บ๋ฆญํฐ ์ค์ : ์๋ฏธ, ์ธ๋, ๋ฏผํ
- โ ๊ฐ์ ์์น: 1~100์
- โ ๋ต๋ณ ์์: ์น์ ํ(Healing), ์กฐ์ธํ(Suggestion), ์ ๋ณดํ(Informative)
- โ ๋ต๋ณ ๊ธธ์ด: ์งง๊ฒ, ๋ณดํต, ์์ธํ
- is New Chat
- ํด๋น Chat์ messages๋ ์ฒ์ ์์ฑํ๋ ๊ฑฐ๋๊น, ์ฒซ ์์ฑํ๋ message document์
is_initial = true
๊ฐ ์ค๋ฒ๋ฆฌ๊ณ ๋ชจ๋ ์์คํ ํ๋กฌํํธ ๋ค ๋๋ ค๋ฃ์.- is_initial = false
- ํ๊ณ์ : ๋งจ ์ฒ์ message document์๋ค๊ฐ ์์คํ ํ๋กฌํํธ ๋๋ ค๋ฃ์ผ๋ฉด, ๋ํ ๋์ค ์์ ํ๋ค๊ธด ํ๋ฐ ๊ฐ๋ฅํ์ง. is_initial = true ์ธ ๊ฒ ์๊ณ , ์์ ๋ ๊ฑฐ๋ฉด, ๊ทธ๊ฑฐ ๋คํ๋จผํธ ์ง์ฐ๊ณ ๋ค์ ๋ฃ์ผ๋ฉด ๋์์. ์ด๋ป๊ฒ๋ ๋ชจ๋ฅด๊ฒ ๊ณ .
- ํด๋น Chat์ messages๋ ์ฒ์ ์์ฑํ๋ ๊ฑฐ๋๊น, ์ฒซ ์์ฑํ๋ message document์
- โ **์ด์
- โ DiaryPage - AI Comment: CRUD ์์ฑํ๊ธฐ
- โ tmp_ai_comment field ์์ ๊ณ , doc_ref ํ์ฉ
- โ DiaryPage - AI Comment: ์บ๋ฆญํฐ ์ค์
- โ tmp_ai_comment_by field ์์ ๊ณ , doc_ref ํ์ฉ
- โ profile_image field ๊ฐ์ผ๋ก ์ด๋ฏธ์ง ์ถ๋ ฅ
-
โ DiaryPage - Drawer - ChatHistoryListTile: order by updated_time
-
โ DiaryPage - Interactive Slider import ํ ์ ์ฉ
-
โ HomeFeedPage: Search Diary ๊ธฐ๋ฅ ๊ตฌํ
- โ CalendarPage(์๋จ) - Mood Calendar
- โ ๋ ์ง๋ณ๋ก ์์ฑ๋ ๊ฒ์๋ฌผ ์ซ์ ํ์ธ ๊ฐ๋ฅ
- โ ๋ ์ง ํด๋ฆญํ๋ฉด, ํด๋น ๋ ์ง๋ก ์ด๋
- โ CalendarPage(ํ๋จ) - Mood stats
- โ ํฌ์ปค์ฑ ๋ ์์ ๊ดํ ํต๊ณ ์๋ฃ ์ถ๋ ฅ
- โ ์ถ๋ ฅ๋ ํต๊ณ ์๋ฃ์ ๋ํ AI์ ์ฝ๋ฉํธ ์ถ๋ ฅ
- โ ํฌ์ปค์ฑ ๋ ์์ ๊ดํ ํต๊ณ ์๋ฃ ์ถ๋ ฅ
-
โ AuthPage: Google Login ๊ธฐ๋ฅ ๊ตฌํ
- โ HomeFeedPage - Bottom Sheet (
+
Button): ๋ค์ํ ์ต์ ์ค 1 ์ ํํ ์ ์๋๋ก- ์๋ก์ด ์ผ๊ธฐ: Go to DiaryPage
- ๊ฐ์ ๊ธฐ๋ก: Go to MoodPage
- โ MoodPage(ํ์
): Mood ์ค์ ์ฌ๋ผ์ด๋ CRUD
- Create
- Read
- Update
- Delete
- โ HomeFeedPage - ListView - FeedCardMood ํ์
-
โ HomeFeedPage - ListView: FeedCardDiary, FeedCardMood, FeedCardChat ์ปดํฌ๋ํธ ์๊ฐ์ ์ ๋ ฌ (Cloud Function ํ์ฉ)
- โ
2025.2.5 ์
๊น์ง ๋ฐํ์ฉ ์ต์ข ๋ฒ์ APK ์ถ์ถ ๋ฐ ์ค์น
๐ญ ์ผ๊ธฐ
์ด์ ๋จ์ ์๊ฐ์ด ์ผ๋ง ์์ด์ ์ข ๋ ๋ง์ด ๊ตฌํํด๋ณด๋ ค๊ณ ํ๋๋ฐโฆ ์ด์ ํด๊ฒฐํ๋๋ผ ์ผ๊ณผ ์๊ฐ์ ๋ค ์ผ๋ค.
๊ทธ๋ฅ ์์ฌ์ ๋ฒ๋ ค์ผ๊ฒ ๋ค. ์ด์ฐจํผ ์ด๊ฑด ์์ดํ ํค์ผ๋ก๋ง ์ ๊น ๋ฐ์ง ๊ฐ๋ฐํ๊ณ ๋๋ผ ํ๋ก์ ํธ๊ฐ ์๋๋๊น.
โจ GPT์ ์ฝ๋ฉํธ (KPT)
โ ์ํ ์ (Keep)
- ๐ FleatherViewer ์
๋ฐ์ดํธ ์ด์ ํด๊ฒฐ:
didUpdateWidget
ํ์ฉ์ผ๋ก ์์ ฏ ์ํ ๊ฐฑ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์ด ํ๋ฅญํ์ด. - โก HomeFeedPage ํํฐ ์ต์ ํ: Query ํํฐ ๋์ Conditional Visibility๋ฅผ ํ์ฉํด ์ฑ๋ฅ์ ์ต์ ํํ ์ ์ด ํจ๊ณผ์ ์ด์์ด.
- ๐ ๋๋ฒ๊น ๊ณผ์ ์์์ ํ์ต: ์ฌ๋ฌ ๊ฐ์ง ์๋๋ฅผ ํตํด Query ํํฐ์ ํ๊ณ๋ฅผ ๊ฒฝํํ๊ณ , Conditional Visibility๊ฐ ๋ ์ ์ ํ๋ค๋ ๊ฒฐ๋ก ์ ๋ด๋ฆฐ ์ ์ด ์๋ฏธ ์์์ด.
โ ์์ฌ์ด ์ (Problem)
- โณ ์์๋ณด๋ค ๋ง์ ์๊ฐ ์์: ์๋ ๊ณํํ๋ ๊ธฐ๋ฅ ๊ตฌํ๋ณด๋ค๋ ์ด์ ํด๊ฒฐ์ ๋๋ถ๋ถ์ ์๊ฐ์ ์ฌ์ฉํ๊ฒ ๋ ์ ์ด ์์ฌ์.
- ๐ ์ด์ ํด๊ฒฐ์ ๋ฏธ๋ฆฌ ์ ๋ฆฌํ์ง ์์: ์ด์ ๋ฉํ ๋ง์์ ๋ฐ์ ์กฐ์ธ์ ์คํํ์ง ์์ ๊ฐ์ ๋ฌธ์ ๋ก ๋ค์ ์๊ฐ์ ์๋ชจํ ์ ์ด ์์์.
๐ ์๋ํด๋ณผ ์ (Try)
- ๐ ์ด์ ํด๊ฒฐ ๋ ธํธ ํ์ฉ: ํด๊ฒฐํ ์ด์๋ฅผ ๊ธฐ๋กํ๊ณ , ๋น์ทํ ๋ฌธ์ ๊ฐ ์๊ธธ ๋ ๋น ๋ฅด๊ฒ ํด๊ฒฐํ ์ ์๋๋ก ์ ๋ฆฌํ๋ ์ต๊ด์ ๋ค์ด์.
- ๐ ๋จ์ ๊ธฐ๋ฅ ๊ตฌํ ์ ๋ต ์กฐ์ : ์ด์ ์๊ฐ์ด ์ผ๋ง ๋จ์ง ์์์ผ๋, ๋ฐ๋์ ํ์ํ ๊ธฐ๋ฅ ์์ฃผ๋ก ์ฐ์ ์์๋ฅผ ์ ๋ฆฌํ๊ณ , ๋๋จธ์ง๋ ์ฐจํ ๊ฐ์ ์ผ๋ก ๋๊ธฐ๋ ์ ๋ต์ ๊ณ ๋ฏผํด๋ณด์.
- ๐ FlutterFlow ๋ด๋ถ ๋์ ๋ฐฉ์ ์ถ๊ฐ ํ์ต: FlutterFlow์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฐฉ์๊ณผ ์์ ฏ ์ํ ๊ด๋ฆฌ์ ๋ํ ์ดํด๋๋ฅผ ๋์ฌ, ๋น์ทํ ๋ฌธ์ ๋ฅผ ๋ฏธ๋ฆฌ ๋ฐฉ์งํ ์ ์๋๋ก ํ์.
๊ฒฐ๋ก
์ค๋์ ์์๋ณด๋ค ์ด์ ํด๊ฒฐ์ ๋ง์ ์๊ฐ์ ์ผ์ง๋ง, ๊ทธ๋งํผ ์ค์ํ ํ์ต์ ์ป์ ํ๋ฃจ์์ด. ๋จ์ ๊ธฐ๊ฐ ๋์ ๊ผญ ํ์ํ ๊ธฐ๋ฅ์ ์ฐ์ ์ ์ผ๋ก ๊ตฌํํ๊ณ , ๋ถํ์ํ ์์ฌ์ ๋ฒ๋ฆฌ๋ ์ ๋ต์ด ํ์ํ ๊ฒ ๊ฐ์. ๋๊น์ง ํ๋ด์! ๐ช๐ฅ
๋๊ธ ๋จ๊ธฐ๊ธฐ