ํด์ปคํค์ด ๋๋ ํ์ ์ฌ๋์ ์ค๋ ๋์ ์ปค๋ฐ ๋ฉ์ธ์ง, ๊นํ์ ์ฌ๋ฌ ๊ธฐ๋ก์ ๊ธฐ๋ฐ์ผ๋ก ํ๊ณ ํด๋ณด๋ ค ํ๋ค.
flutter ์ firebase ๋ฅผ ์ฐ๋ํ์ฌ ์งํํ๋ค.
๋๋ ์๋ฒ๋ฅผ ์์ฃผ๋ก ๊ฐ๋ฐํ๋ค.
github.com/qwa310/DSC-Hackathon
ํด์ปคํค ์ ๋ณด
๋๋ DSC member ์๊ฒฉ์ผ๋ก ์ด ํด์ปคํค์ ์ฐธ์ฌํ๊ฒ ๋์๋ค.
๊ฒฐ๊ณผ๋ฌผ
๋จ ์ผ์ฃผ์ผ๋ง์ 2๋ช ์ด ๊ฐ๋ฐ์ ์ฐธ์ฌํ ์ดํ์ ์์ฐ ์์์ด๋ค.
๋ญ๊ฐ ์ด์ํ ๊ด๊ณ ๋ฉํธ๊ฐ์ง๋ง ์ฑ ๊ฐ๋ฐ์ ๋งน์ธ์ฝ ๋์ ์ฒ์์ด๊ณ ์ฌ์ค ์ ์ฒซ ๊ฐ๋ฐ ๊ฒฝํ๊ณผ ๋ค๋ฅด์ง ์์๋ ํ๋ก์ ํธ
โจ 01.30: ์ฃผ์ ์ ์
์ ์ฒด OT๊ฐ ๋๋๊ณ ํ ๋งค์นญ ๊ฒฐ๊ณผ๊ฐ ๋ฐํ๋์๋ค.
์๋ก ๋ค ๋ค๋ฅธ ํ๊ต์ ์ฌ๋๋ค๊ณผ ์จ๋ผ์ธ(์ฌ๋)์ผ๋ก ์ํตํ๋ฉฐ ์งํํ๋ค.
4๋ช ์ด ํ ํ์ด ๋์๋๋ฐ ๊ฐ ์ฌ๋ ๋น 2๊ฐ์ ์์ด๋์ด๋ฅผ ์ ์ํ๊ธฐ๋ก ํ๋ค.
SC Solution Challenge์์ ๊ณต์ ์ง์ ํ ์ฃผ์ ์ธ UN ์ง์๊ฐ๋ฅ๋ฐ์ ๋ชฉํ UN-SDGs (UN Sustainable Development Goals) 17๊ฐ์ง ์ค ํ ๊ฐ์ง์ ๋ถํฉ๋๋ฉด ๋๋๋ฐ ์ฌ์ค์ ์์ ์ฃผ์ ๋ ๋ง์ฐฌ๊ฐ์ง์ฒ๋ผ ๋๊ปด์ก๋ค. DSC ewha ๋ฉค๋ฒ๋ถ๋ค๊ณผ ์คํ๋ผ์ธ ํ์๋ฅผ ํ๊ณ ์งํ์ฒ ํ๊ณ ์ง ์ค๋ ๊ธธ์ 2์๊ฐ ๋์ ๋จธ๋ฆฌ์ ์ฅ๋ ์ ๋๋ก ์ด์ฌํ ์๊ฐํ๋ค.ํ์์ ๋ง์ ์๊ฐ์ ์ํ๊ณ ์ด์์ ์๋ ์์ด๋์ด๋ฅผ ๋๋ฑ ๋ด ๋์ผ๋ผ๊ณ ํ๋ ๋๋ฌด ์ด๋ ค์ ๋ค.
ํด์ปคํค ๊ธฐ๊ฐ ์ค์ ์ ์ผ ์ ์ ์ ์ผ๋ก ์คํธ๋ ์ค๋ฅผ ๋ง์ด ๋ฐ์ ๋ ์ด์๋ค. ์์ด๋์ด ๋ ธํธ๋ฅผ ํ๋ ์์ฑํด์ ์ถ์ ํด๋์ ํ์๋ฅผ ๋๊ผ๋ค. ๋๋ 11๋ฒ๊ณผ 13๋ฒ์ ๊ด๋ จ๋ ์ฃผ์ ๋ฅผ ๋ผ ์ ์์๊ณ ํฌํ๋ฅผ ํตํด ๋ค๋ฅธ ์ฌ๋์ ์์ด๋์ด๊ฐ ์ฑํ๋์๋ค. (๊ทผ๋ฐ ๋ด ์์ด๋์ด๋ ๊ตฌํํ ๋ง ํ๋ค. ์ธ์ ๊ฐ ๋์ง ์์๊น?)
๊ฒฐ๋ก ์ ์ผ๋ก, ๋ณธ์ธ์ด ์๋นํ๋ ์ ๊ธฐ๋์ ์ธ์งํ๊ณ ์ค์ค๋ก ์ ๊ฒํ๋ฉด์ ์ผ์ ์์์ ๋ฌธ์ ๋ฅผ ๊ฐ์ ํด ๋๊ฐ ์ ์๋๋ก ๋์ธ ์ ์๋ ์ดํ์ ์ฃผ์ ๋ก ์ ํ๋ค.
โจ 01.31: idea ํ์, ๊ฐ๋ฐ ์คํ ์ ์
idea ํ์
๋ค์ ๋ ์ด์ด์ ์์ด๋์ด๋ฅผ ๊ตฌ์ฒดํํ๋ค. ์ ๋ฏผ๋์ ์งํ๋ก ์์ด๋์ด๋ ์์กฐ๋กญ๊ฒ ๊ตฌ์ฒดํ๋์๋ค.
์ฐ๋ฆฌ ์ดํ์ ์ด๋ฆ์ผ๋ก Saver ๊ฐ ์ฑํ๋์๊ณ ์ฐ๋ฆฌ ํ ์ด๋ฆ์ Power Rangers ๊ฐ ๋์๋ค.
๊ฐ๋ฐ ์คํ ์ ์
์ดํ ๊ฐ๋ฐ ์คํ์ ๋ํด ์ฌ์ ์กฐ์ฌ๋ฅผ ํ๋๋ฐ ์์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์๋ค.
์ฌ์ค์ ๋ด๊ฐ (์ฃผํฉ์) ์ ์ผ ๋ฌธ์ ์๋ค.
ํ ๋ถ์ flutter๋ก ์ฑ ๊ฐ๋ฐ์ ํด๋ณด์ จ๊ณ
ํ ๋ถ์ ๊ฐ๋ฐ์๋ก ์ง์ํ์ จ์ง๋ง ์์ง ๊ฐ๋ฐ์ ํ ๋ฒ๋ ํด๋ณด์ง ๋ชปํ๊ณ flutter๋ ์ฌ์ค์ ์ ๋ชจ๋ฅธ๋ค๊ณ ํ์ จ๋ค.
๋ ๊ฐ์ ๊ฒฝ์ฐ๋, ์ง์์์ ๊ฐ๋ฅํ ์คํ์ผ๋ก ๋น๋นํ๊ฒ firebase ํ๋ ์ผ๋์ง๋ผ ๋ด๊ฐ ๋น์ฐํ๊ฒ ๋ง์ถฐ๋๋ฆฌ๋ ๊ฒ ๋ง์๋ค.
์์ด๋์ด๋ ์ฑ์ ๊ฐ๋ฐํ๋ ๊ฒ์ผ๋ก ํ๋ฌ๊ฐ๊ณ ์ฑ ๊ฐ๋ฐ์ ์ ํ ์ ํด๋ณธ ์ ์ด ์์๋ ๋๋ ์ฌ๊ฐ์ฑ์ ๋๊ผ๋ค.
์ผ๋จ ์ฑ ๊ฐ๋ฐ์ ํ๋ ์ฃผ๋ณ ์ฌ๋๋ค์๊ฒ SOS๋ฅผ ์ฒญํ๋ค.
๋๋ถ์ ์์ฃผ ๋น ๋ฅด๊ฒ ์๋๋ก์ด๋ ์คํ๋์ค ์ฌ์ฉ๋ฒ์ ์ด๋ ดํ์ด ๋ณผ ์ ์์๋ค.
๋ถํ ์ค ๋คํ์ธ ๊ฒ์ ๊ธฐ์กด์ ์คํ๋ง/์คํ๋ง ๋ถํธ๋ฅผ intelliJ๋ก ๊ฐ๋ฐํ๋๋ฐ Android Studio ํด์ด inteiiJ ๊ธฐ๋ฐ ์ฑ ๊ฐ๋ฐ ํด์ด๋ผ์ ์ด๋ ต์ง ์๊ฒ ์ ๋ฌธํ ์ ์์๋ค.
๊ฐ๋ฐ ๊ฒฝํ์ด ๋๋ฌด ์์ด์ ๋ถ๊ฐ๋ฅ์ ๋์ ํ๋ ๊ธฐ๋ถ์ด์๋ค.
๊ฐ๋ฐ ์คํ์ flutter + firebase๋ก ์ ํ๊ฒ ๋์๊ณ ๋๋ ๋๋ฌด๋๋ฌด ๋ถ์ํ ๋ง์์ผ๋ก ์ ์ ๋ค์๋ค.
โจ 02.01: ๊ฐ๋ฐ ํ๊ฒฝ ๊ตฌ์ถ
์ค์น๋ถํฐ...
์ผ์ด๋์ ์ผ๋จ android studio, flutter ์ค์น๋ถํฐ ํ๋ค. ์ด์ ์ ๋ฏผ๋๊ป repo ์์ฑ๊ณผ ํ๋ก์ ํธ initial์ ๋ถํ๋๋ ธ๋๋ฐ ํด์ฃผ์ ์ clone ํ ์คํํด๋ณด์๋ค. ๋น์ฐํ์ง๋ง ์คํ์ด ์๋๋ค. 2์๊ฐ ๋์ ๊ฒ์ํด๋ณด๋ฉด์ ์ผ๋จ ์คํ์ ๋๋๋ก ๋ง๋ค์๋ค.
๋ง์ง๋ง ๊ธฐํ ํ์
์ดํ ์คํ 1์์ ๊ฐ์ด ํ์ํ๋ฉด์ ์์ด๋์ด๋ฅผ ๋์ฑ ๊ตฌ์ฒดํํ๋ค. ์ฐ๋ คํ๋ ๊ฒ์ ๋นํด ํ์๋ ์ ๋ง์ ๋ง ๋นจ๋ฆฌ ๋๋ฌ๋ค.
์ฑ ๋น๋ฆฌ๋ฌ ๋์๊ด !
์ ๋ง๋ก ์ด์ ๊ตฌํ์ด ๋ฌธ์ ์๋ค. ํ์๊ฐ ๋๋๊ณ ๋ฐ๋ก ์ปดํจํฐ ์์์ ์ผ์ด๋์ ๋์๊ด์ ํฅํ๊ณ ์ ์งํ๊ฒ flutter, ํ์ด์ด๋ฒ ์ด์ค ํค์๋๋ก ๊ฒ์๋๋ ๋ ์ฑ ์ ์ง์ด์๋ค.
์ง์ ์์ ์ผ๋จ ์ฑ ์ ํผ์ณ๋ค์๋ค.
flutter๋ dart๋ ์ธ์ด๋ก ๊ฐ๋ฐ์ ํ๋๋ฐ ๋์ ์ฒ์ ๋ฃ๋ ์ธ์ด๋ผ์ ์ผ๋จ ๋ฌธ๋ฒ๋ถํฐ ๋ดค๋ค. ๊ฐ์ฒด์งํฅ(java) + js ๋ฌธ๋ฒ์ด ๋ง ์์ฌ์ ์ ์ ์ด ์์๋ค. ๋ณ ๋ฉ์ง ๊ธฐ๋ฅ์ ๋ค ์ง์ํ๋๋ฐ ๋ด๊ฐ ํก์๋ฅผ ํ๋๋ ๋ชปํ๋ ๊ธฐ๋ถ์ด์๋ค. ๋ํ js ๋ ๋ฐ๋๋ผ ์์ค ์ ๋๋ก ์๊ณ ์๋ค๊ฐ es ๋ฌธ๋ฒ์ ์ ํ์์ฑ์ ๋๊ปด ์กฐ๊ธ์ฉ ์ตํ๊ณ ์์๋๋ฐ ์ฝ๋ฐฑ ๊ฐ๋ ์ ์ ํํ ๋ชจ๋ฅด๋ ๋์๊ฒ ์ฅ์ฝ์ด ๋ฐ๋ก ์์๋ค. ๊ทธ๋ฆฌ๊ณ ์ธ์ด๊ฐ indentation์ ๋ ์์ด๋? ๊ธฐ๋ณธ 4์นธ ์ ๋๋ ์์์์ํ๊ฒ ํญ ๋์ด์ผํ๋ ๊ฑด ์๋๋๊ณ . ์๋๋ก์ด๋ ์คํ๋์ค๋ ์๋ฆฌ๋จผํธ๋ก ์ ๊ทผํ๋๋ฐ dart๋ ์ฝ๋ฉ์ ๋์ดํ๋ ์์ผ๋ก ํ๊ณ ๋ฌด์จ 2์นธ์ฉ ๋ค์ฌ์ฐ๊ธฐํ๋ ํ์์ด๋ผ ์ฝ๋๊ฐ ๋์ ๋ค์ด์ค์ง ์์๋ค. ์ด๋ฐ์๋ ๋๋ฌด ๋ต๋ตํ๋ค๊ณ ๋๊ผ๋ค.
PR #1 firebase ์ฐ๋
anyway, ์ด ์ฑ ์ ํตํด ์ผ๋จ ํ๋ก์ ํธ ๊ตฌ์กฐ๋ถํฐ ์ตํ๊ณ Dart ์ธ์ด, ๊ฐ๋จํ ์ค์ต์ผ๋ก ์งง์ ์๊ฐ์ ๊ณต๋ถํ๋ค.
์ดํ firebase ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ ์์ฑ๋ firebase ํ๋ก์ ํธ์ flutter ํ๋ก์ ํธ ์ฐ๋ํ๋ค.
๊ทธ๋ฆฌ๊ณ bigdata.kepco.co.kr/cmsmain.do?scode=S01&pcode=000171&redirect=Y ์ด ํ์ด์ง์ ๋ฐ์ดํฐ ๊ฐ๊ณตํด์ ์๋์ ๊ฐ์ด db์ ์ ์ฅํ๋ค.
์ด๋ ๊ฒ ํ๋ฃจ๊ฐ ๋๋ฌ๋ค.
โจ 02.02: ํ์๊ฐ์ /๋ก๊ทธ์ธ
PR #3 ํ์๊ฐ์ ๊ธฐ๋ฅ ๊ตฌํ
ํ์๊ฐ์ ์ ํ๋ฉด ํ์์ด ์์ฑ๋๊ณ db์ ํ์ ์ ๋ณด๊ฐ ์ ์ฅ๋๋ ์ฝ๋๋ฅผ pr ํ๋ค.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MainPage());
}
firebase๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ๋ฉ์ธ์์ initial ํ๋ ์ฝ๋๋ฅผ ์ฐ๊ณ
void _createUser(User user) {
auth.createUserWithEmailAndPassword(email: user.email, password: user.password)
.then((cred) => {
firestore
.collection('user')
.doc(cred.user.uid)
.set({
'uid': cred.user.uid,
'name': user.name,
'email': user.email,
'region': user.region
})
user ํด๋์ค์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๊ฐ์ ๋ด์ db์ ์ด๋ฆ, ์ด๋ฉ์ผ, ์ง์ญ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ค.
ํ์ ๊ฐ์ ์ ์์ฑ๋ ๊ณ์ ๊ณ ์ ์ uid๋ฅผ db ๋ฌธ์์ ์ ์ฅํด ์ดํ ๋ก๊ทธ์ธ๋ user๋ฅผ ๋์ฑ ์ฐพ๊ธฐ ์ฝ๋๋ก ๊ตฌํํ๋ค.
PR #6 ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๊ตฌํ, ํ์๊ฐ์ /๋ก๊ทธ์ธ ์ค error catch
๋ก๊ทธ์ธ ๊ธฐ๋ฅ๋ firebase authentication ๊ธฐ๋ฅ์ ํ์ฉํ์ฌ ์ฝ๊ฒ ์ฝ๋ฉํ ์ ์์๋ค.
ํ์ง๋ง ์๋ฌ๋ฅผ ์บ์นํ๋ ๊ณผ์ ์์ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ ธ๋ค.
error catch ์ฝ๋๋ฅผ ๋ถ๋ช ์ผ๋๋ฐ ์บ์น๋ฅผ ๋ชปํ๋ค.
stackoverflow.com/questions/54687944/how-to-catch-exception-of-asynchronous-function-in-flutter
์ด ๊ธ์ ํตํด ํด๊ฒฐํ ์ ์์๋๋ฐ, ์ํ๋ ๊ธฐ๋ฅ์ด ์คํ๋ ํ ์๋ฌ๋ฅผ ํ์ธํด์ผํ๋๋ฐ ์ฆ ๋น๋๊ธฐ ํจ์์ ์์ธ๋ฅผ ์ฒดํฌํด์ผํ๋๋ฐ ๊ณ ๋ คํ์ง ์๊ณ ์ฝ๋๋ฅผ ์งฐ๊ธฐ ๋๋ฌธ์ด๋ค.
catch (e) {
if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
} else if (e.code == 'invalid-email') {
print('The email address is badly formatted.');
} else if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else {
print(e);
}
}
๋ก๊ทธ์ธ ๊ธฐ๋ฅ๋
- id์ธ email์ ๋ฑ๋ก๋ ํ์ ์ ๋ณด์์ ์ฐพ์ ์ ์์ ๋๋ e.code == user-not-found ์ฝ๋๋ก,
- ํจ์ค์๋๊ฐ ํ๋ ธ์ ๋๋ e.code == wrong-password ์ฝ๋๋ก
์๋ฌ๋ฅผ ํธ๋ค๋งํ ์ ์์๋ค.
์์ ๊ฐ์ด ์ฝ๋๋ฅผ ๋๊ฒจ๋๋ ธ๊ณ ์๋ฌ๊ฐ ๋ฐ์ํ ์ดํ ํ์ ์ฐฝ์ ํตํด ์ฌ์ฉ์์๊ฒ ์๋ ค์ฃผ๋ ์ฐฝ์ ์์ฑํ๋ ๋ถ๋ถ์ ์ ๋ฏผ๋๊ป์ ๋ฐ๋ก ๊ตฌํํด์ฃผ์ จ๋ค. (PR #7)
์ค์๊ฐ ํ์
๊ฐ์ ๊ฐ์ง๊ณ ์๋ issue ์ ๋ํด์ ์ด์ผ๊ธฐ๋ฅผ ํ๋ค. ๋์์ด๋ ๋ถ๊ป์๋ ์์ ๊ฐ์ด 1์ฐจ ์์ด์ด ํ๋ ์ ์์ฑ ๋ณธ์ ๊ฑด๋ค์ฃผ์ จ๋ค. ์ ๋ ํ์๋ฅผ ํตํด ์ด์ผ๊ธฐํ๋ ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ํด์ ํ๋ฉด์ ๋ผ๋๋ฅผ ๊ทธ๋ ค์ค์ จ๋ค. ์ค๋ช ์ ๋ค์ผ๋ฉด์ ๋ฌด์์ ์ด๋ป๊ฒ ๊ตฌํํด์ผ ํ ์ง ๋ ํ์คํ ์๋ฟ์๋ค. ๋์์ด๋๊ฐ ์๋ ๊ฐ๋ฐ๊ณผ ์๋ ๊ฐ๋ฐ์ ์ฐจ์ด์ ์ ๋ํด์ ๋ง์ด ๋๋ ํ์์๋ค.
โจ 02.03: Create, welcome ํ์ด์ง
PR #8 Create data
ํ๋ก ํธ ์ ๋ฏผ๋์ด ๊ตฌํํด๋์ ์ ์๊ธฐ๊ธฐ ์ข ๋ฅ์ ์ฌ์ฉ์๊ฐ ์ ๋ณด ์ ๋ ฅ ํ์ด์ง์์ submit ๋ฒํผ์ ๋๋ฅด๋ฉด
์๋์ ๊ฐ์ด ๋ก๊ทธ์ธ ๋ ํด๋น ์ ์ ์ ๊ณ ์ id์ ์ ๋ณด๊ฐ ์ ์ฅ๋๋๋ก ๊ธฐ๋ฅ์ ๊ตฌํํ๋ค.
ํ์ง๋ง ์ด db ๊ตฌ์กฐ๋ ๋ค ๋ฐ๋๋ค. firebase๊ฐ ์ง์ํ๋ db์๋ firestore์ realtime database ๋ ์ข ๋ฅ๊ฐ ์๋๋ฐ ๋ ๋ค NoSQL ์ด๋ค. ๊ทผ๋ฐ ๋๋ ์ด ํํ์ ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ฅผ ์ ํ ์ดํดํ์ง ๋ชปํ ์ํ์์ ์ผ๋จ '์ ๋ณด๋ฅผ ์ ์ฅํด๋ณด์'๋ ๊ด์ ์๋ง ์ฃผ๋ชฉํ๊ธฐ ๋๋ฌธ์ 1์ฐจ์ ์ธ ๋ชฉํ๋ ๋ฌ์ฑํด๋์ด์ ๋ฉ์ถ์๋ค.
PR #9 welcome page
์ดํ ๊ตฌํ๋ ํ๋ก ํธ ํ์ด์ง๊ฐ ์์ด์ ์ด๋ค ์์ ์ ๊ณ์ํด์ผํ ์ง ์กฐ๊ธ ๋ฐฉํฉํ๋ค. ๊ทธ๋ฌ๋ค๊ฐ ๋๋ ๊ทธ๋ผ ํ๋ก ํธ๋ฅผ ์์ ํด๋ด์ผ ๊ฒ ๋ค๊ณ ์๊ฐํ๊ณค ์คํ์ ์ฎ๊ฒผ๋ค. ๋ณดํต ์ฑ์ ์คํํ๋ฉด ์ฑ์ด ๋ก๋ฉ๋ ๋ ๋ณด์ฌ์ง๋ ์์ ํ์ด์ง๊ฐ ์๋๋ฐ ์ ์ผ ์ฌ์๋ณด์ฌ์ ์ด ํ์ด์ง๋ฅผ ๊ฑด๋ค์๋ค. ์ด๋ ๊ฒ ๊ตฌํํ๋ ๊ฒ ๋ง๋ ์ถ์์ง๋ง ์์๋ก ์ง์ ํ 4์ด๊ฐ ์ง๋๋ฉด ๊ณ์ ์ ๋ณด์ ์ ๋ฌด๋ฅผ ํ๋จํ์ฌ ๋ก๊ทธ์ธ์ด ๋์ด ์์ง ์๋ค๋ฉด ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋์ด๊ฐ๊ณ , ๊ณ์ ์ ๋ณด๊ฐ ์๋ค๋ฉด ๋ง์ดํ์ด์ง๋ก ๋์ด๊ฐ๋๋ก ๊ตฌํํ๋ค.
์ค์๊ฐ ํ์
โจ 02.04: Read
PR #12 GET mypage data
๊ทธ๋์ CRUD ์ค create ์ ํด๋นํ๋ ์์ ๋ง ํด์๊ณ read ๊ด๋ จ ์์ ์ ์ฒ์ ์๋ํด๋ณด๋ ๋ ์ด์๋ค. ํ๋ก ํธ ์ ๋ฏผ ๋์ด ๋ง์ดํ์ด์ง๋ฅผ ๊ตฌํํ์ ์ ์ด ํ์ด์ง์ ๋ก๊ทธ์ธ๋ ์ ์ ์ ์ ๋ณด๋ฅผ ํธ์ถํด ๋ณด์ฌ์ฃผ๋ ์์ ์ ํ๋ค. ๊ฐ์ฅ ๊ฐ๋จํ read ์์ ์ด๊ธฐ๋ ํ๋ค.
firestore์ ์ธ์คํด์ค๋ฅผ ์์ฑํด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ์ฝ๋๋ฅผ ์์ฑํ๋๋ฐ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ธฐ๋ ์ ์ ๋ง์ดํ์ด์ง๊ฐ ๊ทธ๋ ค์ก๋ค๊ฐ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์จ ๋ค ๋ค์ ๋ง์ดํ์ด์ง๊ฐ ํธ์ถ๋๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค. request/response ๊ฐ๋ ์ ์ ๋ชฐ๋ผ์ ๋ํ๋๋ ์ค๋ฅ์ด์๋ค.
body: StreamBuilder(
stream: currentStream,
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
} return MyPageView(snapshot.data);
},
๋๋ ์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด StreamBuilder๋ฅผ ํ์ฉํ๋ค. (์ด์ ๋ํด ์ ์ ์๋ 1๋ถ ๋์์์ธ๋ฐ ์ ๋ง ๋์์ด ๋ง์ด ๋์๋ค. # ) ๊ฐ๋จํ๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ๋ก์ง์ ์ค๋ช ํ์๋ฉด, ์๋์ผ๋ก ์คํ๋๋ init ํจ์๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ๋ถ๋ฌ์จ๋ค. ์์ง ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ๋ก๋ฉ ํ์ด์ง ( CircluarProgressIndicator() - ๋น๊ธ๋น๊ธ ๋๋ ํ์ด์ง)๋ฅผ ๋ณด์ฌ์ฃผ๋ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ๊ฐ์ ธ์ค๋ฉด ๋ง์ดํ์ด์ง๋ก ๋ฐ์ดํฐ๋ฅผ ๋๊ธด๋ค. ์ดํ MyPageView ์์ ๋ฐ์ดํฐ๊ฐ์ ์ ๊ทผํ์ฌ ๋ ๋๋ง๋ ํ์ด์ง๊ฐ ๋ณด์ด๊ฒ ๋๋ค.
์ด ๊ณผ์ ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ ๊ฐ๊ณตํ๋ ๋ถ๋ถ๊ณผ view ํ์ด์ง๋ฅผ ๋๋์๋ค. ํ ํ์ผ ๋ด์์ ์ฝ๋๊ฐ ๊ธธ์ด์ง๋ ๊ฑด ์๊ฐ ๋ฌธ์ ์๊ณ ๊ฐ๋ ์ฑ ๋ํ ๋ง์ด ๋จ์ด์ ธ์ ์ด๋ ๊ฒ ์์ ํ๋ค. ์ ๋ง ๊ฐ๋จํ read ์์ ์ด์ง๋ง ๋งจ ๋ ์ ๊ตฌ๊ธ๋งํ๋ฉด์ ์ฝ๋๋ฅผ ์ง์ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ ธ๋ ๊ธฐ์ต์ด ๋๋ค.
์ค์๊ฐ ํ์
๋์์ด๋ ๋ฏผ์๋์ด 3์ฐจ์ ๊ฑธ์ณ์ ์ต์ข ์ ์ธ ํ์ด์ง ๊ตฌ์ฑ์ ์๋ฃํ์ จ๋ค. ์ด ํ์ผ์ ๋ณด๋ฉด์ ๋์์ธ์ ์๋๋ฅผ ์ค๋ช ๋ค์ผ๋ฉด์ ๋์์ธ๊ณผ ๊ด๋ จ๋ ๋ ผ์๋ ๋๋๊ฒ ๋์๋ค. ์ด์ด์ ์ฌ๋ฆ๋๊ป ๋ถํ๋๋ ธ๋ `์ ์๊ธฐ๊ธฐ ๋ณ ํ๊ท ์ ์ธ ์๋น ์ ๋ ฅ ์กฐ์ฌ ํ์ผ`์ ๋ฐ๊ณ ๊ด๋ จ ์ค๋ช ์ ๋ค์๋ค. ํ๋ก ํธ ์ ๋ฏผ๋๊ณผ ์๋ฒ ํํธ๋ฅผ ๋งก์ ๋๋ ๊ฐ๋จํ๊ฒ ์ด์์ ๋ํด์ ๋๋์๋ค. ์ต์ข ๋ฐํ ์์ ์ ์ถ๊ณผ ๊ด๋ จํด์ ์ญํ ์ ๋ถ๋ดํ ๋ค ํ์๋ฅผ ์ข ๋ฃํ๋ค.
โจ 02.05: ๊ธฐ๋ฅ ๋ง๋ค๊ธฐ
PR #17 add 60% process
ํ๋ก ํธ ๊ตฌํ ์๋๋ณด๋ค ๋ฐฑ์๋ ๊ตฌํ ์๋๊ฐ ๋ ๋นจ๋๋ค. ํ๋ก ํธ์ ๋ฐฑ์๋๊ฐ ๋ง์ด ์ ๊ธฐ์ ์ผ๋ก ์ฐ๋๋๋ ํ๋ก์ ํธ์ ๊ฒฝ์ฐ, ๋ณดํต ํ๋ก ํธ๋ฅผ ๋จผ์ ๋์ถฉ ๊ตฌํํ ๋ค ๋ฐ์ดํฐ๋ฅผ ์ ํ๋ ์์ผ๋ก ์์ ํด์๋ค. ํด๋น ํ๋ก์ ํธ๋ ์์ ์ค๋ช ํ ๊ฒฝ์ฐ์ ์ํ๋๋ฐ, ์ด๋ฒ์๋ ๋์์ด๋๋ถ๊ป์ ์ ์ํด์ฃผ์ ํ์ด์ง๋ฅผ ํ ๋๋ก ๋ฐฑ์๋ ๋ก์ง์ ๋จผ์ ์์ฑํ ์ ์์๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ๋ณต์กํ๊ฒ ํ์ผ์ด ๋ง์์ ธ๋ฒ๋ ธ๋ค. ์ด์ ๊ด๋ จ๋ ๋ด์ฉ์ ์๋ดํด๋๋ฆด ํ์๋ฅผ ๋๊ปด์ ํ๋ก ํธ ์ ๋ฏผ ๋์ด ๋ณด๊ธฐ ์ฝ๊ฒ ๊ทธ๋ฆผ์ ํ ์ฅ ๊ทธ๋ ค์ pr์ ๊ทธ๋ฆผ๋ ์ฒจ๋ถํ๋ค. ์ด์ ์์ ์๊ฐํ๋ xd ๋ผ๋ ์์ฃผ ๋๋ํ ํด์ ์ฐ๊ณ ์๋๋ฐ ์ ์์ ์์ฑํ๋ ์ถ๋ค.
๊ฐ๋จํ๊ฒ ์์ ํ ๋ด์ฉ์ ๋ฆฌ์คํธ์ ํด๋ณด์๋ค.
- /calendar ์ด๋ ์ ํ์ฌ ๋ ๋ ํจ์๋ก ๋ถ๋ฌ์ค๊ธฐ
- user collection ์ db ๋ชจ๋ธ๋ง ํ๊ธฐ
- /crud ๋ฐ๋ db ๋ชจ๋ธ์ ๋ง์ถฐ create ๋ฌธ ์์ ํ๊ธฐ
- /my_power ์ ๋ฌ์ ์๋น ์ ๋ ฅ๊ณผ ํ์ฌ ์๋น ์ ๋ ฅ
- /my_power2 ํ์ด์ง ์์ฑํ๊ธฐ
- /my_town ์ ์ (์ ์ ์ ๋์) ๋ถ๋ฌ์ค๊ธฐ
- /home ์ ์ ์ ๋ณด ๋ถ๋ฌ์ค๊ณ , ๋ค๋น๊ฒ์ด์ ์ญํ ์ ํ ์ ์๋๋ก ์์ฑ๋ ํ์ด์ง ์ฐ๊ฒฐํ๊ธฐ
db๋ ์๋์ ๊ฐ์ด ๋ฐ๋์๋ค.
user (collection) ใ ก uid (document) ใ ก 2021-02 (collection) ใ ก device (document) ํ์์ผ๋ก ์ด์ด์ง๊ณ ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ํ ์คํ ํด๋ณด๋ฉด์ ์ด ๋ชจํ์ด ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ ๊ณ์ฐํ๋ ์์ ์ ํ ๋ ํธํ๋ค๊ณ ์๊ฐํด์ ์ด๋ ๊ฒ ์งํํ๋ค. 2~3๋ฒ ์ ๋ ๊ฐ์์์๋ ๊ฑธ๋ก ๊ธฐ์ตํ๋ค.
์ ์์ ๋ค ์ค ๊ฐ์ฅ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ ธ๋ ํ์ด์ง๋ /my_power ํ์ด์ง์ด๋ค.
๋์ ๊ฒฝ์ฐ์, ๋ฐ์ดํฐ๋ฅผ 2๋ฒ ์ฝ์ด์ค๋ ์์ ์ ํ๋๋ฐ StreamBuilder๋ฅผ 2๋ฒ ์ฐ๋๋ก ์์ ํ๋ค. ๊ธฐ์กด์ ํ ๋ฒ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ฌ ๋ StreamBuilder๋ฅผ ์ผ๋ ๊ฒ์ ๋ณํํด์ ์ผ๋ค. ๊ตฌ๊ธ๋ง์ ํ ๋๋ก ์ต๋ํ ์ฝ๊ฒ ์ฝ๊ฒ ๊ตฌํํ๊ณ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ธ์ง๋ ์ ๋ชจ๋ฅด๊ฒ ๋ค. ๋๋ ์ด ๋ฌธ์ ๋ก ๊ฝค ๊ณ ์์ ํ๋ ๊ธฐ์ต์ด ์์ด์ ์ฝ๋ ์ ๋ฌธ์ ์ฒจ๋ถํด๋๋ค.
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'my_power_page_view.dart';
class MyPowerPage extends StatefulWidget {
final String date;
num total = 0;
MyPowerPage (this.date);
@override
_MyPowerPageState createState() => _MyPowerPageState();
}
class _MyPowerPageState extends State<MyPowerPage> {
FirebaseFirestore firestore = FirebaseFirestore.instance;
FirebaseAuth auth = FirebaseAuth.instance;
Stream<QuerySnapshot> currentStream;
void initState() { // [1] ์ง๋ ๋ฌ์ ์ ๋ ฅ ์๋น๋ ๋ถ๋ฌ์ค๊ธฐ
super.initState();
currentStream =
firestore.collection('user').doc(auth.currentUser.uid).collection(widget.date).snapshots();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: currentStream,
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
// [2] lastMonth์ total ๊ณ์ฐํ๊ธฐ
snapshot.data.docs.forEach((element) {
widget.total += element['calculate'];
});
return initCurrent(); // [3] initCurrent() ํธ์ถํ๊ธฐ
},
),
);
}
initCurrent() { // [4] ํ์ฌ ๋ฌ์ ์ ๋ ฅ ์๋น๋์ order์ ๋ง๊ฒ ๋ถ๋ฌ์ view์ ๋ฐ์ดํฐ ๋๊ฒจ์ฃผ๊ธฐ
Stream<QuerySnapshot> document =
firestore.collection('user').doc(auth.currentUser.uid).collection(widget.date)
.orderBy('calculate', descending: true).snapshots();
return StreamBuilder(
stream: document,
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
} return MyPowerPageView(widget.date, snapshot.data.docs, widget.total);
},
);
}
}
์ ๋ง ๋ง์ ํ์ด์ง๋ฅผ ์์ฑํด์ ์์ ์ ํด๋์ด์ ๋์กฐ์ฐจ๋ ์ปค๋ฐ ๋จ์๋ฅผ ์ด๋ป๊ฒ ์ชผ๊ฐ์ ์ด๋ค ๋ฉ์ธ์ง๋ฅผ ์ ์ด์ผ ํ ์ง ๊ณ ๋ฏผ์ ๋ง์ด ํ๊ฒ ๋ ๊ฒ ๊ฐ์ ๋ฌดํฑ๋๊ณ ํ๊บผ๋ฒ์ ์ปค๋ฐํด๋ฒ๋ ธ๋๋ฐ ๋ ๊ณ ๋ฏผํด๋ณด๊ณ ์ ์ ๊ฑธ ๊ทธ๋ฌ๋ค. ์ฝ๋ ์์ฑํ๋ ๊ณผ์ ์ด ์ ๋๋ฌ๋์ง ์์ ์์ฌ์์ ๋จ๋๋ค.
์ค์๊ฐ ํ์
๋ค์ ๋ ๊ตฌํ ๋ฐ๋ชจ ์์์ ์ ์ถํด์ผ ํด์ ์์ ์ ์์ ๋งก์ผ์ ๋ฏผ์๋๊ป์ ์งํ ์ํฉ์ ๋ํด์ ์ฌ์ญค๋ณด์ จ์๋ค. ๊ธ์์ผ๋ 10์ 20๋ถ๋ถํฐ ์งํํ ํ์๊ฐ ๋ ์์ง๋ ์์ํ๋ค. ํ์์์ ๋ด๊ฐ ํ์ฌ๊น์ง ๊ตฌํ๋ ์ดํ ์์ฐ๊ณผ ํจ๊ป ์งํ ์ํฉ์ ์์ธํ ์ค๋ช ํ๋ค. ํ์ง๋ง ์ ์ง๋ฌธ์๋ ๋๋ ๋ด๊ฐ ์ด๋๊น์ง ๊ตฌํํ ์ ์์์ง ๊ฐ์ด ์์กํ์ ๋ถ์ํ ๊ฐ์ ์ ์ฐ์์ด์๋ค. ๊ทธ๋์ ๋ค์ ๋ 9์ ์ ๋๊น์ง ๊ตฌํ๋ ๋ด์ฉ์ผ๋ก ๊ธฐ๋ฅ ๋ฆฌ์คํธ ์ ํ ํ ๊ธฐ๋ฅ ๊ด๋ จ ๋๋ณธ์ ์ง ๋ค๊ณ ํ์ จ๋ค.
โจ 02.06: ๋ฐค์, ์ ์ถ
์ด์ ๋ ์ด์ ๋ฌผ๋ฌ๋ ๊ณณ์ด ์์๋ค. ์์ฑ ๋ชปํ ๊ธฐ๋ฅ์ ์๋๋ฃฉ์ธ๋ฐ ์์ฑ์ ํด์ผ ํ๋ค. ์ด์ฌํ ๋ฌ๋ ธ๋ค !
PR #19 add update, delete logic, calculate logic
์ ํ์ด์ง์ update ๊ธฐ๋ฅ
firestore
.collection('electronics').where("device", isEqualTo: device).get()
.then((QuerySnapshot ds) {
var defaultValue = ds.docs[0]['Wh'];
firestore
.collection('user')
.doc(auth.currentUser.uid)
.collection(_getCurrentYearAndMonth())
.doc(device)
.set({
'device': device,
'usage_time': double.parse(time),
'calculate': double.parse(time) * double.parse(defaultValue)
}).then((value) {
Navigator.pushReplacementNamed(context, '/crud');
update์ ๊ฒฝ์ฐ create๋ฅผ ์คํํ๋ ๊ฒฝ์ฐ์ 100% ์ฝ๋๊ฐ ๋์ผํ๊ฒ ์จ๋ ์๋์ ํ๋ค. firebase์ ๋๋ํ ๋ถ๋ถ์ ๋๋ ์ ์๋ค. ํ์ง๋ง ์ด๋ ๊ฒ ์์ฑํ๋ ๋ฐ๋์, created_date ์ modified_date ์ ๋์ผํ ๊ฐ์ด ์ ์ฅ๋๋ค. ํ์ง๋ง ์ฐ๋ฆฌ์ ์๋น์ค์์๋ ์์ ์๊ฐ์ ๋ณด์ฌ์ฃผ๋ ํ์ด์ง๋ ์๊ณ , ์ค์ํ์ง ์์์ ๋นผ๋ฒ๋ ธ๋ค.
ํด๋น ์ฝ๋๋ฅผ ์กฐ๊ธ ๋ ์ค๋ช ํด๋ณด๋ ค ํ๋ค. ์ฌ์ฉํ ์ ์๊ธฐ๊ธฐ์ ์ฌ์ฉํ ์๊ฐ์ ์ ๋ ฅ๋ฐ์ ์ ์ฅ ๋ฒํผ์ ๋๋ฅด๋ฉด ์์ ์ฝ๋๋ฅผ ํ๋ค. 1. ์ ์๊ธฐ๊ธฐ์ ์๊ฐ ๋น ํ๊ท ์ ์ธ ์๋น ์ ๋ ฅ๋์ db์ ์ ์ฅํด๋์๋๋ฐ ๊ทธ ๊ฐ์ ์ฐพ์์จ๋ค. 2. ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ์ ๋ณด์ ํจ๊ป ์ ์๊ธฐ๊ธฐ๊ฐ ์ฌ์ฉํ ์ ๋ ฅ ์๋น๋์ ๊ณ์ฐํ ๊ฐ์ db์ ์ ์ฅํ๋ค. 3. ์ ๋ฐ์ดํธ๋ ์ ๋ณด๋ก ํด๋น ํ์ด์ง์ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๋ถ๋ฌ์จ๋ค.
์ ํ์ด์ง์ delete ๊ธฐ๋ฅ
firestore
.collection('user')
.doc(auth.currentUser.uid)
.collection(_getCurrentYearAndMonth())
.doc(device)
.delete()
.then((value) {
Navigator.pushReplacementNamed(context, '/crud');
์ง์ฐ๊ณ ์ถ์ ์ ๋ณด๊ฐ user collection์ uid๋ก ๋ doc ์์ ์ ์ ์ฅ๋น ์ด๋ฆ์ผ๋ก ๋์ด ์์ด์ ์ด๋ ต์ง ์๊ฒ ์ญ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค. ์ด ์ฝ๋๋ ๊ฐ๋จํ๊ฒ ์ญ์ ํ ํ ์ญ์ ๋์์์ ๋ฐ๋ก ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ํด๋น ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๋ถ๋ฌ์ฌ ์ ์๋๋ก Navigator.pushReplacementNamed() ๋ฅผ ์ฌ์ฉํ๋ค.
์๋น ์ ๋ ฅ ๊ณ์ฐ ๊ณผ์
๋ ์ง๋ฅผ ๋ค๋ฃจ๋ ๊ฑด ์๊ฐ๋ณด๋ค ๊น๋ค๋กญ๋ค. ์ผ๋จ ์ ๊ณตํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ ํ์ฉํด์ผ ํ๊ณ ๋ณ์ ์ด๋ฆ์ ์ ์ง์ด์ผํ๋ค. ๊ทธ๋์ผ ๊ณ์ฐ์์ ์ฐ๋ ๊ณผ์ ์์ ๋ด๊ฐ ์ํ๋ ๊ฐ์ ์ ๋๋ก ์ค์์์ด ์ธ ์ ์๊ณ ํ์ ์ ์ง๋ณด์๋ ํธํ ๊ฒ์ด๋ค. ๋ฐ๋ก ์ง์ ํ๊ธฐ์ ์๋ฐํ๋ก๊ทธ๋๋ฐ ๋ฐ ์ค์ต ๊ณผ๋ชฉ์์ ๊ธฐ๋ง์ด ์์จ ํ๋ก์ ํธ๋ก ๋์ฒด๋์ด์ ๋๋ ๋ฌ๋ ฅ ๊ธฐ๋ฅ์ด ์๋ gui๋ฅผ ๊ฐ๋จํ๊ฒ ๊ฐ๋ฐํ์๋๋ฐ ๊ทธ ๋ ๊ฒฝํ์ด ๋์์ด ๋์ด์ ๋ ๋น ๋ฅด๊ฒ ์์ฑํ ์ ์์๋ค.
์ฌ๊ธฐ๊น์ง์ ๊ฐ๋ฐํ๊ณ ์ค์ 3์ ์ ๊ฐ์ Pull Request๋ฅผ ๋ณด๋๋ค.
PR #20 give parameter clicked month info
์ด์ ์ฌ์ฉ์๊ฐ ํธ์ถํ ๋ -๋ฌ์ด ์ธ์ ์ธ์ง ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์์ค๋ ์์ ๋ง ๋จ์๋ค. ๊ทผ๋ฐ ์ด ์์ ์ด ์ ๋ง ๋ง๋ง์น ์์๋ค.
"2021-02"์ ๊ฐ์ด String์ผ๋ก ํด๋ฆญํ ๋ฌ์ ๊ฐ์ ์ธ์๋ก ๋ฐ๊ธฐ ์ํด์ onGenerateRoute ๋ฅผ ํ์ฉํ๋ ๊ฒ์ด ์ ์์ ์ธ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ํด์ ๋์
ํด๋ดค๋ค. parameter๋ก ์ฃผ๋ ๊ฒ ์์ฒด๋ ์ด๋ ต์ง ์์๋๋ฐ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ ์ํด์ initState์ ๊ฐ์ ๋๊ฒจ์ฃผ์ด์ผ ํด์ ๋๋ฌด ๊น๋ค๋ก์ ๋ค.
์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์ฐ๋ฉด ์คํ์ ๋๋๋ฐ ์ดํ๋ฆฌ์ผ์ด์
์ ์คํํ ๋๋ง๋ค ์ถ์์ ์ธ ์๋ฌ ๋ก๊ทธ๊ฐ ๋ฌ๋ค. ๊ผฌ๋ฐ 3์๊ฐ๋์ ์ด ์์
์ ํ๋ฉด์ stackoverflow๋ฅผ ์ ๋ง ์ ๋
ํ๋๋ฐ ๋ ์ด์ ์๊ฐ์ ์ง์ฒดํ ์ ์๋ค๊ณ ์๊ฐํด์ ์ด ๋ช์์ ์ผ๋จ ๋ฒ์ด๋๊ธฐ๋ก ํ๋ค. ๋๋ ์๋์ ๊ฐ์ด ๊ตฌํํ๋ค.
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'my_page.dart';
import 'welcome.dart';
// ... ์๋ต
import 'my_power_page.dart';
import 'my_power2_page.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MainPage());
}
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Main Page',
debugShowCheckedModeBanner: false,
initialRoute: '/welcome',
routes: {
'/welcome': (context) => Welcome(),
'/my_page': (context) => MyPage(),
},
onGenerateRoute: (RouteSettings settings) {
var routes = <String, WidgetBuilder>{
'my_power': (context) => MyPowerPage(settings.arguments),
'my_power2': (context) => MyPower2Page(settings.arguments),
// ... ์๋ต
};
WidgetBuilder builder = routes[settings.name];
return MaterialPageRoute(builder: (ctx) => builder(ctx));
},
theme: ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
),
);
}
}
class MyPowerPage extends StatefulWidget {
final String date;
MyPowerPage(this.date); // ์์ฑ์๋ฅผ ํตํด ์ธ์๋ฅผ ๋ฐ๋๋ค.
num totalLast = 0;
num totalCurrent = 0;
@override
_MyPowerPageState createState() => _MyPowerPageState();
}
class _MyPowerPageState extends State<MyPowerPage> {
FirebaseFirestore firestore = FirebaseFirestore.instance;
FirebaseAuth auth = FirebaseAuth.instance;
Stream<QuerySnapshot> currentStream;
// [1] lastMonth ๋ถ๋ฌ์ค๊ธฐ
void initState() {
super.initState();
DateInfo dateInfo = new DateInfo(widget.date); // widget.date ๋ก ํ์ฉ ๊ฐ๋ฅ
currentStream = firestore
.collection('user')
.doc(auth.currentUser.uid)
.collection(dateInfo.lastYear + "-" + dateInfo.lastMonth)
.snapshots();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: currentStream,
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
print(snapshot);
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
// [2] lastMonth์ total ๊ณ์ฐํ๊ธฐ
snapshot.data.docs.forEach((element) {
widget.totalLast += element['calculate'];
});
return initCurrent();
},
),
);
}
// [3] currentMonth, calculate order์ ๋ง๊ฒ ๋ถ๋ฌ์ view์ ๋๊ฒจ์ฃผ๊ธฐ
initCurrent() {
Stream<QuerySnapshot> document = firestore
.collection('user')
.doc(auth.currentUser.uid)
.collection(widget.date)
.orderBy('calculate', descending: true)
.snapshots();
return StreamBuilder(
stream: document,
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
// [2] lastMonth์ total ๊ณ์ฐํ๊ธฐ
snapshot.data.docs.forEach((element) {
widget.totalCurrent += element['calculate'];
});
DateInfo dateInfo = new DateInfo(widget.date);
if (DateFormat('yyyyMM').format(DateTime.now()) ==
dateInfo.currentYear + dateInfo.currentMonth) {
// ํ์ฌ๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ -> ๊ณ์ฐ๋ฐฉ์: ํ์ฌ ์ฌ์ฉ๋ - ์ ๋ฌ๋์์ฌ์ฉ๋ * (ํ์ฌ ์ผ ์/์ ๋ฌ์ ์ผ ์)
var result = widget.totalCurrent -
(widget.totalLast *
num.parse(dateInfo.currentDate) /
num.parse(dateInfo.lastMonthOfDay));
return MyPowerPageView(widget.date, snapshot.data.docs, result);
} else {
// ๊ณผ๊ฑฐ์ ๋ฌ์ ํธ์ถํ ๊ฒฝ์ฐ -> ๊ณ์ฐ๋ฐฉ์: ๊ณผ๊ฑฐ์ ๋ฌ ์ฌ์ฉ๋ - ๊ณผ๊ฑฐ์ ๋ฌ์ ์ง ์ ๋ฌ ์ฌ์ฉ๋
var result = widget.totalCurrent - widget.totalLast;
return MyPowerPageView(widget.date, snapshot.data.docs, result);
}
},
);
}
}
์ค์ 6:46, PR ํ๋ค.
PR #21 fix bug
์ค์ 8:02, ๋ฐํ ๋๋ณธ์ ์จ์ฃผ์๋ ๋ฏผ์ ๋๊ป ์ฌ๊ธฐ๊น์ง ๊ตฌํ๋ ๊ธฐ๋ฅ์ ๋ฆฌ์คํธ ์ ํด์ ๋ณด๋ด๋๋ ธ๋ค.
PR #23 fix bug
์ค์ 11:42, Pull Request๋ฅผ ๋ณด๋๊ณ ์ฌ๊ธฐ๊น์ง๋ก ๊ธฐ๋ฅ ๊ตฌํ์ ๋ง๋ฌด๋ฆฌํ๋ค.
PR #25~26 apply font, Style up
๋ฐ๋ชจ ์์์ ์ฐ์ผ๋ ค๊ณ ํ๋๋ฐ ๊ธฐ๋ฅ์ ์ ๋ณด์ด์ง๋ง ํ๋ก ํธ์์ ๊ฑฐ์ฌ๋ฆฌ๋ ๋ถ๋ถ์ด ๋ง์๋ค. ๋จผ์ NanumSquare ํฐํธ๋ฅผ ์ ์ฉํ๋๋ฐ ํฐํธ๋ฅผ ์ ์ฉํ์๋ง์ ๋ด๊ฐ ํ๋ ํ๋ก์ ํธ๊ฐ ๋ง๋ ์ถ์ ์ ๋๋ก ๋๋ฌด ์๋ป์ ธ์ ๊ฐ์ด์ด ์ ์ฅํด์ก๋ค ใ _ใ ํ๋ก ํธ๋ ๊ฑฐ์ ๋ชจ๋ฅด์ง๋ง ์ง๊ธ๊น์ง ๊ตฌํ๋ ์ฝ๋์ ๋์น๊ป ์ ํ์ฉํด ํ๋ฉด ์์ ๊ณผ ๋์์ ๋ฐ๋ชจ ์์์ ๋ถ๋ถ์ ์ผ๋ก ์ฐ์ด ๋๋ ธ๋ค. ๋ค์ ๋ด์ญ๋ค์ ๋ณด๋ ํ๋ก ํธ๋ ์๊ฐ๋ณด๋ค ๋ง์ด ๊ณ ์ณค๋ค !
PR #29 end of hackathon, ์ ์ถ
- feat(crud): update dropdownbar to textfield - /crud ํ์ด์ง์์ ์ฌ์ฉ ์๊ฐ์ ์ฌ์ฉ์๊ฐ ์ง์ ์ ๋ ฅ๋ฐ์ ์ ์๋๋ก ์์
- ์ด ์ธ ์ฝ๋ ์คํ์ผ ๋ง์ถ๊ธฐ, ํ์ ์๋ ํ์ด์ง ์ญ์
์ด๋ก์จ ์คํ 4์ 23์ผ๋ก ํด์ปคํค ๋ง๊ฐ ์๊ฐ์ธ 5์ ์ด์ ์ผ๋ก ๋ง์ง๋ง pr๋ฅผ ๋ณด๋๋ค. ๋ญ ๋จน์ ์ฌ์ ๋ ์์๋๋ฐ ๋ฐฅ ๋ช ์๊ฐ๋ฝ ๋จ๊ณ ๋ฐ๋ก ๊ฐ์ ์ค๋ ๊ธฐ์ต์ด ๋๋ค.
โจ 02.07: ๋ณด์
PR #30 link calendar data and fix bugs
๋ค์๋ ์ผ์ด๋ ๋ค์ ์ดํ์ ์คํํด๋ดค๋๋ฐ ์์ฌ์ด ๋ถ๋ถ๋ค์ด ๋์ ๋ฐํ๋ค. ๊ทธ๋์ ๋ค์ ์ปดํจํฐ๋ฅผ ์ผ์ ์ด์ด์ ์กฐ๊ธ ์์ ํ๋ค.
- ์บ๋ฆฐ๋์์ ๋ ๋ ์ด๋ ํ ํด๋นํ ๋ ๋์ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ฃผ์ง ์๋ ๋ฒ๊ทธ ์์
- crud ํ์ด์ง์์ ๋ค๋ก๊ฐ๊ธฐ๋ฅผ ๋๋ฅด๋ฉด ๋์ค๋ ํํ์ด์ง์์์ ์ ๋ณด๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๊ณ์ฐ๋์ง ์์๋ ๋ฒ๊ทธ ์์
- ์ด ๋ถ๋ถ์ ๊ตฌ๊ธ๋งํด์ onWillPop์ ๋์ ํด๋ดค๋ค.
return new WillPopScope (// ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ ๋๋ ์ ๋
onWillPop: () { // ์์ธ ์์ ฏ์ ์ญ์ ํ๊ณ ํ์ผ๋ก ์ด๋(๋ฐ์ดํฐ์๋ก๋ถ๋ฌ์์ผํด์)
Navigator.pushNamedAndRemoveUntil(context, '/home', (route) => false);
return;
},
- ์ด๋ค ์์๋ก ์ ๋ ฌ๋ ํ์ด์ง์ธ์ง ์๋ ค์ฃผ๋๋ก ํ์ดํ ์์
- ์ฌ์ฉ์๊ฐ ์ด๋ค ์ ๋ณด๋ฅผ ๋ณด๊ณ ์๋์ง ๋ ์ง๊ด์ ์ผ๋ก ์ ์ ์๋๋ก ์๋์ ๊ฐ์ด ๊ณ ์ณค๋ค.
๋๋ ์
๋ถ๊ฐ๋ฅํ๋ค๊ณ ๋งค์ผ ์๊ฐํ๋๋ฐ ์๊ฐ๋ณด๋ค ๋๋ฌด ์์ฑ๋ ์๊ฒ ๋ง๋ฌด๋ฆฌ ๋์๋ค. (์ ์ด๋ ๋๋ ๊ทธ๋ ๊ฒ ์๊ฐํ๋ค...!) ๊ทธ๋์ ๋๋ ๋ด๊ฐ ์ ๊ธฐํ๋ค. ์ด๋ผ? ์ง์ง ๋ด๊ฐ ๊ฐ๋ฐ์ ํ๊ณ ์๋ค? ๊ฐ ์ ์ฒด์ ์ธ ํ๊ธฐ์ด๋ค. ๊ทธ๋์ ๊ฐ๋ฐ ์์ฒด๊ฐ ์ฌ์ค ๋ฌด์์ธ์ง ์ ๊ฐ๋ ์์ค๊ณ ๋ฐฐ์์ ๋์ด ๋ณด์ด์ง ์์์ ์ง์น ์ฆ์์ด์๋๋ฐ ์ฑ์ฅ ๊ฐ๋ฅ์ฑ์ ๋๋ ์ ์์๋ ์์คํ ์๊ฐ์ด ๋์๋ค. ๋ง์คํ ์ฑ ์๊ฐ์ผ๋ก ํ๋ค์๋ ๊ฑด ์ฌ์ค์ด์ง๋ง ๋จ ์๊ฐ์ ์ฑ์ฅํด๋ฒ๋ฆฐ ๊ธฐ๋ถ์ด๋ค. ์ด ์ฑ์ฅํ๋ ๋๋์ด ์ ๋ง ์ง๋ฆฟํ๋ค. ์ ๋ง ์์ ๋ก์ง๋ถํฐ ํ๋์ฉ ๊ตฌํํ์ ๋ ๋ฐ๋ ค์ค๋ ์ฑ์ทจ๊ฐ์ด ๋ค์ ๋๋ ฅ์ด ๋๋ ๊ฑธ ๋๊ผ๋ค. ์ด๊ฑด ๋ง์น ๋ฌดํ ๋๋ ฅ์ด ์๋๊น ์ถ์ ๊ธฐ๋ถ์ด์๋ค. ์... ์ด๋์ ๊ฐ๋ฐ์๋ฅผ ํ๋๋ณด๋ค. ํ๋ค์ง๋ง ์ ๋ง ๋งค๋ ฅ ์๋ ์ง์ ์ด๋ค.
๊ทธ๋์ ๋๋ฌด ํ๋ค๊ฒ ์ฝ์งํ๋ ์์ฃผ ์์ ๊ฒฝํ ๊ฒฝํ๋ค์ด ํ์คํ ๋์์ด ๋์๋ค. db ๋ณด๋ฉด ํ์ ๊ฐ์ ์ ์์ฑ๋ ์ ์ ์ ๊ณ ์ ์์ด๋(uid)๋ฅผ user collection์ document ์ด๋ฆ์ผ๋ก ๋งค์ฐ ์ค์ํ๊ฒ ์ฐ๊ณ ์๋๋ฐ, ์ด์ ์ ํ๋ก์ ํธํ๋ฉด์ ์ด๊ฑฐ ์ ์ฅํ๋๋ฐ๋ง ์ง์ง๋ก 24์๊ฐ ์ฝ์งํ์๋ค. ๊ผฌ๋ฐ ํ๋ฃจ๋ฅผ ์จ์ ํ! ์ฐ๊ณ ๋ค์๋ ์ผ์ด๋์๋ 8์๊ฐ์ ์ ๊ฒ๋ง ์ฐพ์๋ดค๋ค. ๊ทธ ๋๋ ์ ๋ง ์ ๊ฒ ๋๋ฌธ์ ์จ๊ฐ ์์ ๋ค ํ๊ณ ๋ฏธ์น ๋ป ํ๋... ๊ธฐ์ต์ด ๋งค์ฐ ์์ํ๋ค. ๋์ค์ ๋ firebase ๋ก ํ๋ก์ ํธ๋ฅผ ํ๊ฒ ๋ ์ง๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง ์ด ๋ ๊ฐ๋ฐํ๋ ์ฝ๋ ์กฐ๊ฐ์กฐ๊ฐ์ด ํ์ํด์ง๋ ๋ ์ด ์์ ๊ฒ ๊ฐ๋ค.
ํ์ java๋ก ๊ฐ๋ฐ์ ํ๋ค๊ฐ dart๋ ์๋ก์ด ์ธ์ด๋ฅผ ์ ํ๊ฒ ๋์๋๋ฐ, ์ธ์ด๊ฐ ๋ฌ๋ผ๋ ์ฌ์ค ์ ๊ณตํด์ฃผ๋ ๋ฉ์๋๋ค์ด ํฌ๊ฒ ๋ค๋ฅด์ง ์์์ ๋์น๊ป ์ค๋ฅ ๋นจ๊ฐ์ค ์๋จ๊ฒ ์์ฑํ๋ฉด ๋์๊ฐ๋ค. ์ด ๋ถ๋ถ๋ ์ฌ์ค ์ข ์ ๊ธฐํ๋ค. ๊ทธ๋ ๋ค๊ณ ๋น์ฐํ ๋ง์ด์ง๋ง ์ ๋ค๋ฃฌ๋ค๋ ๊ฑด ์๋๋ค. ๋ค์ flutter๋ก ๊ฐ๋ฐํ ๊ธฐํ๊ฐ ์๊ธฐ๋ฉด ๊ฐ๋ ํ์ด์ฃผ๋ ์ฑ ์ด๋ ๊ฐ์๋ฅผ ๋ค์ ๋ณด๋ ์๊ฐ์ ๊ฐ์ง ๊ฒ์ด๋ค.๊ฒฝํ์ ํด๋ดค์ผ๋ ๋น ๋ฅด๊ฒ ์ตํ๊ณ ๋ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํํ ์ ์์ ๊ฒ ๊ฐ๋ค. ๊ทธ๋ฆฌ๊ณ js ์ es ๋ฌธ๋ฒ๋ค์ ์ตํ๊ณ ์์ด์ผ ํ ๊ฒ ๊ฐ๋ค. ํ๊ธฐ๊ฐ ์์ํ๊ณ ์๊ฐ์ด ๋๋ฉด ํํํ ๊ฐ๋จํ ๊ณต๋ถํ ๊ฒ์ด๋ค.
๋ง์ง๋ง์ผ๋ก ํ๋ ์ ๋ง๋ ๊ฒ ๊ฐ๋ค ! ์ด์ ๊ฐ๋ํ์ ์ ๋ฏผ๋ ๋๋ถ์ ์ง์น์ง๋ง ํ๋ก ํธ ๊ตฌํํ๊ณ ๊ณ์ค ์ ๋ฏผ๋ ์๊ฐํ๋ฉด์ ์ปดํจํฐ ์์ ์์์์ ์ ์์๋ ๊ฒ ๊ฐ๋ค. ๋งค์ผ ์จ๋ผ์ธ์ผ๋ก ์ฌ์ง์ ์ฐ์๋๋ฐ ์ค์ ๋ก ๋ต ๊ธฐํ๊ฐ ์๊ฒผ์ผ๋ฉด ์ข๊ฒ ๋ค *-*
'๊ฐ๋ฐ์ด์ผ๊ธฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ผ์ฃผ์ผ๋์ ๊ฐ๋จํ๊ฒ ํด๋ก ์ฝ๋ฉ #springboot (0) | 2021.06.18 |
---|---|
[pickmeup] ํซํ ํ๊ทธ ๊ตฌํํ๊ธฐ (0) | 2021.02.18 |