μΉμ¬μ΄νΈΒ Β Β Β Β
νλ μ΄μ€ν μ΄Β Β Β Β Β
React Native GitHubΒ Β Β Β Β
React GitHub (Migration μ )
νλ‘μ νΈ κΈ°κ°: 2023.09.29 ~ 2023.11.16 | 리ν©ν λ§ κΈ°κ°: 2023.11.20 ~ μ§ν μ€
체νκ³μ ID: [email protected] | PW: 123qwe
- π¨βπ»π©βπ» ν μκ°
- π οΈ κΈ°μ λ° κ°λ° νκ²½
- π‘ μ£Όμ κΈ°λ₯
- π ν΅μ¬κΈ°μ
- π νΈλ¬λΈ μν
- πββοΈ μ μ νΌλλ°±
- π λ²μ 2(λ§μ΄κ·Έλ μ΄μ , κΈ°λ₯μΆκ°)
- π₯ Firebase ꡬ쑰
- π νλ‘μ νΈ κ΄λ ¨ λ¬Έμ
- μ€νλμ
- λ‘κ·ΈμΈ λ° νμκ°μ
- λμ μ¨λ²/곡μ μ¨λ² 리μ€νΈ
- μ¨λ² μ λ ¬(μ΅μ μ/μ€λλμ)
- μ¨λ² μΆκ°/μμ /μμ
- μ¨λ² 곡μ
- μ¨λ²μ νΌλ μ¨λ²ν
- μ¨λ²μ μ¬μ§ μΆκ°
- νΌλ μμ
- μ¨λ²μ νΌλ 리μ€νΈν
- νΌλ μμ /μμ /μ¨λ² λ³κ²½
- μ¬μ§ λ° μ λͺ© (νμ)
- λ³Έλ¬Έ, λ μ¨/κΈ°λΆ μ΄λͺ¨ν°μ½, μμΉ (μ ν)
- νλ‘ν μμ
- νμνν΄ λ° λ‘κ·Έμμ
- μ΄μ©μ½κ΄ λ° κ°μΈμ 보μ²λ¦¬λ°©μΉ¨
1) μ¨λ² 곡μ
- κΈ°λ₯ μκ°
- 곡μ ν μ¬μ©μλ₯Ό κ²μν μ μλ€.
- μ¨λ²μ 곡μ νκ±°λ, 곡μ ν λμμ μμ ν μ μλ€.
- νμμ 곡μ νκ±°λ 곡μ λ°μ μ¨λ²μ λ³Ό μ μλ€.
- μ¨λ²μ 곡μ λ°μΌλ©΄, ν΄λΉ μ¨λ²μ μ μ₯λ μ¬μ§μ λ³Ό μ μλ€.
- μ½λ
- μ¬μ©μ κ²μ - Firebase Admin SDKλ₯Ό μ¬μ©νμ¬, μ¬μ©μλ₯Ό λΆλ¬μ¨λ€.
```js
// src/app/api/user/route.ts
adminApp.auth().getUserByEmail(email);
```
- 곡μ /곡μ μ·¨μ - Firestore Databaseμ 곡μ μ 보 μ μ₯&μμ
```
// [uid]/[uid]
sharedAlbums: Reference(albumDoc)[]
// [uid]/[uid]/album/[albumId]
sharedUsers: {uid, permission}[]
```
-
ν - 곡μ μ¨λ² - Firestoreμμ λ‘κ·ΈμΈν μ¬μ©μμ 곡μ μ¨λ² 리μ€νΈλ₯Ό κ°μ Έμ¨λ€. ```js // src/utils/SDKUtils.ts
const getSharedAlbums = async ( uid: string, ): Promise<DocumentReference[]> => { const userDocRef = doc(appFireStore, uid, uid); const userDoc = (await getDoc(userDocRef)).data(); return userDoc.sharedAlbums; }; ```
- 곡μ μ¨λ² λ°μ΄ν°λ₯Ό λΆλ¬μ¨λ€.
```js
// src/app/api/album/sharing
sharedAlbums.map(async (ref: DocumentReference) => {
const albumData = await getDoc(ref).data();
// (μ€λ΅)
});
```
- 곡μ ν μ¬μ©μ λ°μ΄ν°λ₯Ό λΆλ¬μ¨λ€.
```js
// src/app/api/album/sharing
const { displayName, email } =
await adminAppAuth.getUser(sharedAlbumUserUid);
```
- 곡μ μ¨λ² μμΈ - νΌλ 리μ€νΈλ₯Ό μ»κΈ° μν΄ κ³΅μ μ¨λ²/λμ μ¨λ² ꡬλΆμμ΄ μμ²μ 보λΈλ€.
```js
// src/services/feed.ts
// Path Parameter(uid, albumName)λ₯Ό 쿼리 맀κ°λ³μλ‘ μμ²μ μΆκ°νμ¬ μ μ‘
// μ¨λ² μμΈνμ΄μ§ κ²½λ‘: {uid}/album/{albumName}
// νΌλ μμΈνμ΄μ§ κ²½λ‘: {uid}/album/{albumName}/feed
await fetch(
`${API_URL}/feed?limit=${limit}&skip=${skip}&album=${albumName}&uid=${uid}`,
);
```
- μΏ ν€μ uid(λ‘κ·ΈμΈν μ¬μ©μ)μ 쿼리 맀κ°λ³μλ‘ λ°μ uid(μ¨λ² μμ±μ)κ° λ€λ₯Ό κ²½μ° κΆνμ κ²μ¬νλ€.
```js
// src/app/api/route.ts
export async function GET(req: NextRequest) {
// μ€λ΅
let hasPermission = true;
if (userUid !== uid) {
const sharedAlbums = await getSharedAlbums(userUid);
hasPermission = await checkAlbumPermission(albumDoc, sharedAlbums);
}
if (!hasPermission) {
return new Response('μ κ·Ό κΆνμ΄ μλ μ¨λ²μ
λλ€.', {
status: 403,
});
}
// μ€λ΅
}
```
2) Masonry Layout
-
CSS
- λΆλͺ¨ μμ CSS
// src/containers/albumDetail/StyledFeed.ts const StyledFeedList = styled.ul` display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: -8px -8px; grid-auto-rows: 1px; `;
- μμ΄ν CSS
// src/components/AlbumItem/StyledAlbumItem.ts const StyledAlbumItem = styled.li` margin: 8px; `;
-
JS
- gridRowEnd κ°μ κ³μ°νλ 컀μ€ν ν
// src/hooks/useAlbumItemLayout.ts interface ImgSize { width: number; height: number; } function useAlbumItemLayout(node: HTMLLIElement) { const [imgSize, setImgSize] = useState<ImgSize | null>(null); const [gridRowEnd, setGridRowEnd] = useState(''); useEffect(() => { const setLayout = async () => { if (!imgSize || !node) { return; } const height = node.clientWidth * (imgSize.height / imgSize.width); setGridRowEnd(`span ${Math.round(height + 16)}`); }; setLayout(); }, [imgSize]); return { setImgSize, gridRowEnd }; }
- gridRowEnd κ°μ κ³μ°νκΈ° μν΄ νμν μμ΄ν μ΄λ―Έμ§ μ¬μ΄μ¦ ꡬνκΈ°
// src/components/AlbumItem/AlbumItem.tsx <img onLoad={(e) => setImgSize({ width: e.currentTarget.naturalWidth, height: e.currentTarget.naturalHeight, }) } />
1) μλλ‘μ΄λ κΈ°κΈ°μ λ€λ‘κ°κΈ°
-
λ€λ‘κ°κΈ° ν΄λ¦ μ, μ±μ΄ λ«νλ μ΄μ
- ν΄κ²°: μ΄μ νμ΄μ§κ° μ‘΄μ¬ν κ²½μ°, μ΄μ νμ΄μ§λ‘ μ΄λνλλ‘ μμ -
λ€λ‘κ°κΈ° ν΄λ¦ μ, κ²μλ¬Ό μ λ‘λ/μμ λͺ¨λ¬μ΄ κ³μ μ΄λ €μλ μ΄μ
- μμΈ: κ²μλ¬Ό μ λ‘λ/μμ λͺ¨λ¬μ΄ νμ΄μ§ μμ μ»΄ν¬λνΈμμ λ λλ§λκΈ° λλ¬Έμ, μ΄μ νμ΄μ§λ‘ μ΄λν΄λ λͺ¨λ¬μ λ«νμ§ μμ
- ν΄κ²°: λͺ¨λ°μΌμμ κ²μλ¬Ό μ λ‘λ/μμ λͺ¨λ¬μ νμ΄μ§λ‘ λ³κ²½ -
κ²μλ¬Ό μ λ‘λ/μμ ν κ²μλ¬Ό μμΈνμ΄μ§μμ λ€λ‘κ°κΈ° ν΄λ¦ μ, κ²μλ¬Ό μ λ‘λ/μμ νμ΄μ§λ‘ λμκ°λ μ΄μ
- μν©: κ²μλ¬Ό μ λ‘λ/μμ νλ©΄μΌλ‘ λμκ°λ νλ¦μ΄ λΆνΈνλ€λ νΌλλ°±μ λ°μ
- ν΄κ²°: λͺ¨λ°μΌμμλ κ²μλ¬Ό μ λ‘λ/μμ μ λͺ¨λ¬λ‘ λλλ¦¬κ³ , λ€λ‘κ°κΈ° ν΄λ¦ μ λͺ¨λ¬μ΄ λ«νλλ‘ λ³κ²½
2) μ΄λ―Έμ§ νμ₯μ μ ν¨μ± κ²μ¬ - SVG
-
λ¬Έμ : μ΄λ―Έμ§ μ ν ν μ ν¨μ± κ²μ¬ μ, svg νμΌμ΄ ν΅κ³Όνμ§ λͺ»νλ λ²κ·Έ
-
μμΈ: κΈ°μ‘΄μ svg νμΌμ image/svgλ‘ κ²μ¬νκ³ μμμΌλ, νμ€ MIME νμ μ image/svg+xmlμ΄κΈ° λλ¬Έ
-
ν΄κ²°: image/svg+xmlμ ν΅κ³Όμν€λλ‘ μ κ· ννμ μμ
/^image\/(jpg|svg|png|jpeg|gif|bmp|tif|heic)$/ // κΈ°μ‘΄ /^image\/(jpg|svg(\+xml)?|png|jpeg|gif|bmp|tif|heic)$/ // λ³κ²½
3) λͺ¨λ¬ λ°°κ²½ μ½ν μΈ μ€ν¬λ‘€
-
λ¬Έμ : λͺ¨λ°μΌμμ κ²μλ¬Ό μ λ‘λ/μμ λͺ¨λ¬ λ΄ μ€ν¬λ‘€ μλ μ, λ°°κ²½ μ½ν μΈ κ° μ€ν¬λ‘€λλ κ²½μ°κ° μμ
-
μμΈ: ν΄λΉ μμμ μ€ν¬λ‘€μ (λ) λ΄λ¦΄/μ¬λ¦΄ μ μλ κ²½μ°, windowμ μ€ν¬λ‘€ μ΄λ²€νΈ λ°μ (chrome λμ λ°©μ)
-
ν΄κ²°: λͺ¨λ°μΌμμ ν΄λΉ λͺ¨λ¬ open μ, bodyμ scroll-rock ν΄λμ€ μΆκ° (close μ, scroll-rock ν΄λμ€ μμ )
.scroll-lock { position: fixed; height: 100vh; overflow: hidden; }
4) λ°μ΄ν° μ λ°μ΄νΈμ UI
-
λ¬Έμ : λ°μ΄ν° μ λ°μ΄νΈ μ, λ€λ₯Έ κ²½λ‘λ‘ μ΄λν ν λμμ€λ©΄ μ΄μ λ°μ΄ν°κ° λ λλ§λ¨
-
ν΄κ²°: λ°μ΄ν° μ λ°μ΄νΈ μ λΌμ°νΈ μλ‘κ³ μΉ¨
import { useRouter } from 'next/navigation'; router.refresh();
νΌλλ°± λͺ©λ‘
νμκ°μ
μ΄μ©μ½κ΄ μ½κ³ λ€λ‘ μ€λ©΄ μ λ ₯ν΄ λμλ λ΄μ©μ΄ μ¬λΌμ§κ³ , λͺ¨λ μ²΄ν¬ λ°μ€κ° ν΄μ λ¨5a0b0d0νλ‘ν μ¬μ§ λ³κ²½ λ²νΌμ λ§μ°μ€ 컀μλ₯Ό κ°μ Έλ€ λμμ λ, μκ°λ½ λͺ¨μμΌλ‘ λ°λλ©΄ μ’κ² μbdfc9ea- λ²νΌ νλ¨λΆκ° μλ¦Ό. μ±μ΄ μ 체μ μΌλ‘ νλ¨λΆ UIκ° μλ¦Ό
'μλ νμΈμ λͺ¨λ¬΄μ λλ€'λΌλ ν μ€νΈκ° μμΌλ©΄ μ’μ κ² κ°μ. μ΄λ―Έ μ€νλμμμ μκ°νκΈ° λλ¬Έ4f05ab6μμ΄λκ° λ‘κ·ΈμΈμ©μΈμ§ μ¬λλ€μκ² λ³΄μ΄λ μ©μΈμ§ λͺ¨λ₯΄κ² μ(username -> nickname)
νλ‘ν μμ
νλ‘ν μμ κΈ°λ₯μμ μ¬μ§ ν¬κΈ° 2MB μ΄λ΄λΌμ νΈλν°μΌλ‘ μ°μ μ¬μ§μ λ±λ‘μ΄ μ λ¨(src/hooks/useProfileImg.ts)κ³μ μ¬μΈμ¦ λͺ¨λ¬ - λΉλ°λ²νΈκ° λ§μ€νΉ μ²λ¦¬λλ©΄ μ’κ² μ7e75388νλ‘ν μ€μ μ΄ μμ μΈ κ±΄μ§ ν·κ°λ¦Ό6167780νν΄ λͺ¨λ¬ νλ¨λΆκ° μλ¦Ό#227
ν
- νλ¬μ€ μμ΄μ½μ΄ μ¨λ² μΆκ° λ²νΌμΈμ§ ν·κ°λ¦Ό
μ¨λ² μ΄λ¦μ μ λ ₯νμ§ μμλ μ¨λ² μΆκ° κ°λ₯#236μ¨λ² μμ /μμ λͺ¨λ¬μ μλ μ²΄ν¬ νμμ κΈ°λ₯μ λͺ¨λ₯΄κ² μ(μ μ₯ λ²νΌ: μ²΄ν¬ μμ΄μ½ -> 'μ μ₯' ν μ€νΈ)μ¨λ² μμ± μ, μν°λ₯Ό λλ¬μ μ μ₯ κ°λ₯νλ©΄ μ’κ² μ91d0fe3κ°μ μ΄λ¦μΌλ‘ μ¨λ²μ μ¬λ¬ κ° λ§λ€ μ μμ#236νμ¬ μ¨λ²(λ보기 ν΄λ¦ μ, μ ν λͺ¨λ¬μ΄ λ¨λλ‘ λ³κ²½)01e4d5fb825983...
λ²νΌ(λ보기) ν΄λ¦ μ, μ¨λ² μμ /μμ λͺ¨λ¬μ΄ μ΄λ¦¬λλ° κΈ°λ₯μ λͺ λ£ννλ©΄ λ μ’μ κ² κ°μμ¨λ² νλ¨λΆκ° μλ¦Ό571a714μ¨λ²λͺ μ μ λ ₯νκ³ μ μ₯ λ²νΌμ μ¬λ¬ λ² λλ₯΄λ©΄ μ¨λ²μ΄ μ¬λ¬κ° μμ±λ¨692c719μ¨λ² μμ /μμ λͺ¨λ¬μ λ²νΌμ μ¬λ¬ λ² λλ₯΄λ©΄ μλ¬ νμ΄μ§("μ‘΄μ¬νμ§ μλ νμ΄μ§μ λλ€")λ‘ μ΄λλ¨#236
μν© μ¬ν: λ²νΌμ΄ μμΉν κ³³μ κ³μν΄μ ν΄λ¦νλ©΄, μμ±μ΄ μλ£λ λ λͺ¨λ¬μ΄ λ«νλ λμμ μ¨λ²μ΄ ν΄λ¦ λ¨ -> ν΄λ¦ λ μ¨λ²μ μ λͺ©μ΄ μμ μ, μ ν¨νμ§ μμ μ£Όμλ‘ μ΄λλ¨λͺ¨λ¬μ°½μ΄ λμμ‘μ λ λ²νΌμ λλ¬μ§μ§ μμ§λ§ μ€ν¬λ‘€μ΄ κ°λ₯ -> μΌλ°μ μΈ μ¬μ©μ±μ΄λ, κ²μλ¬Ό μ λ‘λ/μμ λͺ¨λ¬μ κ²½μ° λͺ¨λ°μΌμμ νλ©΄ μ 체λ₯Ό μ°¨μ§νκΈ° λλ¬Έμ μ¬μ©μ λΆνΈν¨μ΄ μμ#143μ¨λ² νν° λ²νΌμ΄ λ무 μμ036022aμ¨λ² μ λͺ© κΈμ μμ μ νμ΄ μμ536bae6μ λ ¬ κΈ°μ€ λλ₯΄κ³ λμ λ€λ₯Έ λΆλΆ ν°μΉνμ λ μ λ ¬μ°½μ΄ κΊΌμ‘μΌλ©΄ ν¨9b16fbf
μ¨λ² μμΈ νμ΄μ§
κ²μκΈμ΄ λ§μμ§μλ‘ 'μ¨λ²μ κ²μκΈ μΆκ° λ²νΌ'λ λ€λ‘ λ°λ €μ λλ₯΄λ¬ κ°κΈ° νλ€μ΄μ§5bbe7dd63fa419λͺ©λ‘ν, μ¨λ²ν μ ν κ°λ₯νλ©΄ μ’κ² μfe9614f- λ μ§, μ λͺ©μ΄ 보μμΌλ©΄ μ’κ² μ
κ²μλ¬Ό μμΈ νμ΄μ§
μ λͺ©κ³Ό λ³Έλ¬Έμ΄ κΈμ ν¬κΈ° μ°¨μ΄κ° ν¬κ² μ λμ μμμ΄λ ν°νΈ μ¬μ΄μ¦λ₯Ό μ’ λ μ‘°μ νλ©΄ μ’κ² μ17cc95d
κ²μλ¬Ό μ
λ‘λ
ν λ²μ μ¬λ¬ μ₯μ μ¬μ§μ λ±λ‘ν μ μμΌλ©΄ μ’κ² μ=> λΈλΌμ°μ νμΌ μ ν κΈ°λ₯ μ΅μμ§ μμ μ¬μ©μ- μ²μμ λͺ¨λ selectboxκ° λ«νμμ΄μ ν λ² λ λλ¬μΌ νλ κ² μ¬μ©μ±μ΄ μ μ’μ κ² κ°μ
- λκ° μ§λμ νμ μμ§μ¬μ μμΉλ₯Ό μ νν μ μλ κΈ°λ₯μ΄ μμΌλ©΄ μ’κ² μ
μ²΄ν¬ νμκ° μμΉ μΆκ° λ²νΌμ΄λΌλ κ²μ μκΈ° μ΄λ €μ μ#52μ λ‘λ λ²νΌμ ν¬μ»€μ€κ° λ§μ§λ§μ λλ©΄ μ’κ² μ#74μ€λμ λ μ¨μμ λΉμ λμ ꡬλΆμ΄ λͺ¨νΈν¨89f4104- μ§λμμ λ΄κ° μνλ λΆλΆμ ν°μΉνμ¬ μ§μ ν μ μμΌλ©΄ μ’κ² μ
- μμΉ μΆκ°λμ μ΄μμ λ, μλλ‘ λλκ·Ένμ¬ μ€λμ λ μ¨λ λ³Ό μ μμΌλ©΄ μ’κ² μ
μ¨λ²μ΄ 볡μ μ ν κ°λ₯ν΄μ μ’μESCλ₯Ό λλ₯΄λ©΄ λͺ¨λ¬μ΄ λ«νλ©΄ μ’κ² μ61d1e8aκΈ°μ‘΄ μ¬μ§μ μΆκ°ν μ¬μ§λ§ μ ννλλ°, κΈ°μ‘΄ μ¬μ§μ μμ΄μ§#269μ¬μ§μ΄ μ΅λ 3μ₯μ΄ μ¬λΌκ°λλ° λ°λ‘ μλ΄ μ¬νμ΄ μλ μ μ΄ μμ¬μ#269- μμΉ μΆκ°μ κ²½μ° μ§λμ νμλλ μ₯μλ₯Ό νλνκ³ μΆμνλ κΈ°λ₯μ μ¬μ©ν λ λ§μ½ inputμ 컀μκ° λ€μ΄κ° μλ κ²½μ° (κ²μμ΄λ₯Ό μ λ ₯νκ³ λ°λ‘ μ§λλ₯Ό νλνλ κ²½μ°) νλ μΆμν λλ§λ€ inputμ μκΎΈ ν¬μ»€μ€κ° λ€μ΄κ°. inputμμ ν¬μ»€μ€λ₯Ό λΉΌμΌ(λ€λ‘κ°κΈ° λ²νΌ λλ¬μΌ) κΉλνκ² νλμΆμκ° κ°λ₯ν¨
- κ²μμ΄λ₯Ό λͺ¨νΈνκ² μ λ ₯νμ λ μ νμ§κ° μλκ² μμ¬μ(μμΈλ‘ μ λ ₯νλ©΄ 경볡κΆμ΄ μ νλ¨)
νμ νλͺ©μ μ μ μμ΄μ λΆνΈν¨#269- μ¨λ² μ ν μ, μλ‘μ΄ μ¨λ²μ λ§λ€μ΄μ κ·Έ μ¨λ²μ λ°λ‘ μΆκ°ν μ μμΌλ©΄ μ’κ² μ
μ¬μ§ μ λ‘λ λ²νΌμ ν¬μ»€μ€κ° λλ©΄ μ’κ² μ#74- μ¬μ§λΏλ§ μλλΌ λμμλ μ μ₯ν μ μμΌλ©΄ μ’κ² μ
- νλ°κ° μμ΄λ μ’μ λ―ν¨
μ λ‘λλλ μ¬μ§μ νμ₯λͺ μ μΆκ°νλ©΄ μ’κ² μ(gif λ±)#53κ²μλ¬Ό μ λͺ©κ³Ό κ²μλ¬Ό λ³Έλ¬Έμ 곡백 ν¬ν¨ 500μκΉμ§ μ ν μμ(μλ΄ νμ)#269μμΉ μ ν μ, μ§λκ° λ¨μ§ μλ λ²κ·Έ(Kakao Developersμ μ£Όμ μΆκ°)λ μ¨μ κΈ°λΆ μ λ νΈ λ°μ€κ° μ νλμ§ μλ λ²κ·Έ(κ²μλ¬Ό μ λ‘λ 22 λ²κ·Έλ‘ μΈν λ²κ·Έ)
μ±
μλλ‘μ΄λ κΈ°κΈ°μ λ€λ‘κ°κΈ° λ²νΌμ λλ₯΄λ©΄ μ±μ΄ μ’ λ£λ¨dc43540
κΈ°ν
μ€ν¬λ‘€μ νλ©° κ³μν΄μ κ²μκΈμ λ³΄κ³ μΆμfe9614fμ¨λ²μ νμλ‘ μμ±ν΄μΌ μ¬μ§μ΄ μ λ‘λν μ μκ±°λ, μ¨λ² μμ± μ μ¬μ§μ μ λ‘λν΄λ κΈ°λ³Έ μ¨λ²μ μ¬μ§μ΄ μ λ‘λλλ©΄ μ’κ² μ(
μν©: νμκ°μ μ, 'μ 체 보기' μ¨λ²μ΄ μλ μμ±λλ μ¬μ©μλ μΈμ§νμ§ λͺ»ν¨
ν΄κ²°1: κΈ°μ‘΄μ μ λ‘λ ν μ΄λν νΌλ μμΈ νμ΄μ§μμ ν΄λΉ νΌλμ λν μ λ³΄λ§ λ³Ό μ μμ. 'μ 체 보기'μ νΌλ μμΈ νμ΄μ§λ‘ μ΄λνλλ‘ λ³κ²½νμ¬, 'μ 체 보기' μ¨λ²μ΄ μλ μμ±λκ³ ν΄λΉ μ¨λ²μ μ μ₯λμμμ μΈμ§ν μ μλλ‘ ν¨${userUid}/μ 체 보기/feed
)
ν΄κ²°2: νμκ°μ μ, νν 리μΌμ¬μ§ μ¬λΌμ΄λκ° λμνμ§ μμ3aabb70
3-1. μ λ‘λ
3-2. κ²μλ¬Ό μμΈ νμ΄μ§#35κ²μκΈ μμ ν κ²μκΈμμ#32<
λ€λ‘κ°κΈ° μμ΄μ½μ λλ₯΄λ©΄ λ€μ κ²μκΈ μμ νμ΄μ§κ° λμμ λΆνΈν¨
- κ°μ : κ²μλ¬Ό μμ νμ΄μ§ -> λͺ¨λ¬λ‘ ν΅μΌκ²μκΈ μμ λ₯Ό νλ©΄ κΈ°μ‘΄μ μλ νμ΄μ§κ° μλλΌ μ κ²μκΈ μμ±νλ νμ΄μ§κ° λμμ λΆνΈν¨ - μν©: κ²μλ¬Ό μμ± ν μμ μ μ΄μ νμ΄μ§μΈ μ κ²μκΈ νμ΄μ§λ‘ μ΄λλ¨ - κ°μ : μ κ²μκΈ νμ΄μ§(κ²μλ¬Ό μ λ‘λ νμ΄μ§) -> λͺ¨λ¬λ‘ ν΅μΌ#39confirm μ°½μ΄λ alertμ°½μ μ§μ λ§λ€μ§ μμμ UIκ° μμμ§ μμ#191- μΊλ¦°λ νμμΌλ‘ μ λ‘λν λ μ§λ₯Ό μ§μ ν΄ νμΈν μ μλ κΈ°λ₯μ΄ μμΌλ©΄ μ’κ² μ
- μ± μ κΈ κΈ°λ₯μ΄ μμΌλ©΄ μ’κ² μ
곡μ κΈ°λ₯ μΆκ° ν¬λ§#253- μμ μ΄λ―Έμ§ μ¬μ§μΌλ‘ λ§λ€μ΄μ Έ μ¬μ§μΌλ‘ 곡μ ν μ μμΌλ©΄ μ’κ² μ
λ΄λΉκ²μ΄μ λ°μ ν λ²νΌμ΄ a νκ·Έμ button νκ·Έλ‘ μ΄λ£¨μ΄μ Έμ ν¬μ»€μ€κ° λ λ² λ¨(#241)https://github.com/yonainthefish/MoMoo/issues/241[https://github.com/yonainthefish/MoMoo/commit/270938caf1635d0ee1eb806c8d0c7cd91535da98]λͺ¨λ¬μ΄ λμμ λ, λͺ¨λ¬ λ΄μμλ§ ν¬μ»€μ€κ° μ΄λνλ©΄ μ’κ² μ(#245)[yonaisgood/MOMOO-React#245]μ ν¨νμ§ μμ URL μ μ μ, λ΄λΉκ²μ΄μ λ°λ λμ€λ©΄ μ’μ κ² κ°μ(#231)[yonaisgood/MOMOO-React#231]μμ΄μ½μ ν리ν°κ° λ λ°μ νλ©΄ μ’κ² μ- μ±μ 컨μ
μ΄ λ λΆλͺ
νλ©΄ μ’μ κ² κ°μ
15-1. μ¬μ§ μ λ‘λ λ©μΈμΌ κ²½μ°, μ¨λ² μμΈ νμ΄μ§μμ μ¬μ©μκ° μ λ‘λν μ¬μ§λ€μ΄ λͺ¨μμ λ λΏλ―ν¨μ λλ λ§ν λμμΈ μμ μΆκ°νλ©΄ μ’κ² μ
15-2. μΌκΈ° κΈ°λ₯μ΄ λ©μΈμΌ κ²½μ°,
- ν°νΈ μμ± λ³ν κΈ°λ₯μ μΆκ°νλ©΄ μ’κ² μ
- λμ ν루 κΈ°λΆμ μ£Όκ°/μκ° κ·Έλνλ‘ νμΈν μ μλ κΈ°λ₯ μΆκ°νλ©΄ μ’κ² μ
- ν°νΈ μμ± λ³ν κΈ°λ₯μ μΆκ°νλ©΄ μ’κ² μ
νν 리μΌμ΄λ μ¬μ©λ²μ μλ €μ£Όλ κΈ°λ₯μ΄ μμΌλ©΄ μ’κ² μμ΄μ©κ°μ΄λμ¨λ²μ΄ μ¬λ¬ κ°κ° λλ κ²½μ° μ€ν¬λ‘€μ΄ λ무 κΈΈμ΄μ Έμ νΈλν°μ κ°€λ¬λ¦¬μ²λΌ μμλ μ’μ λ― ν¨- μ μ²΄λ³΄κΈ°κ° μμ μ κ°νν¨
λ§μ΄νμ΄μ§ μ°½μμ μ μ νλ‘ν κΈ°λ₯μ λ°λ‘ μ¬μ©νμ§ μλλ€λ©΄ λΉΌλ©΄ μ’κ² μ(λλ μ€ μκ³ λͺ λ² ν΄λ¦ν¨)#91- λ€λ₯Έ μ¬λκ³Όμ μ±ν κΈ°λ₯μ΄ μμμΌλ©΄ μ μ ν κ² κ°μ
*μ΄ 70κ°μ νΌλλ°±μ λ°μμ΅λλ€. νμ¬ 53κ°λ₯Ό λ°μ μλ£νμ΅λλ€.
μ¬μ© λ§μ‘±λ κ°μ
- 1μ°¨ λ§μ‘±λ μ‘°μ¬ λλΉ νκ· μ½ 29% ν₯μλ¨ (4λ² μ μΈ)
- β 10μ λ§μ
- νμκ°μ /λ‘κ·ΈμΈ/νλ‘ν μμ : β 7.3 -> β 10
- μ¨λ² μμ±/μμ /μμ : β 7.7 -> β 9.5
- κ²μλ¬Ό μ λ‘λ/μμ /μμ : β 6.7 -> β 10
- μ¨λ² 곡μ : 10
νΌλλ°± λͺ©λ‘
ν
- 'λ보기'λ₯Ό λλ₯΄λ©΄ (μμ νκΈ°, 곡μ λμ) μ΄μΈμ μμ νκΈ°λ μμμΌλ©΄ ν¨
- μ¨λ²μμ μ¬μ§μ λλ₯΄κ±°λ νλλ₯Ό ν΅ν΄ μ¬μ§μ μ’ λ μμΈν λ³Ό μ μμΌλ©΄ μ’μ κ² κ°μ
μ¨λ² ν΄λ¦ μ, 404 νλ©΄μ΄ λ¨λ κ²½μ°κ° μμ -> μ¨λ² μ΄λ¦μ΄ '.'μΈ κ²½μ°#145
κ²μλ¬Ό μμΈ
μ€μ μ λ‘λν λ μ§μ λ€μλ λ‘ λμ΄412e163
κ²μλ¬Ό μ
λ‘λ/μμ /μμ
- κΈ°μ‘΄μ μ¨λ²μ λ€μ΄κ° μλ μνμμ μ λ‘λλ₯Ό λλ¬λ μ¨λ² μ νμ λ°λ‘ λλ¬μΌ νλλ°, λ§μ½ μ¨λ²μ λ€μ΄κ° μνμμ μ λ‘λνκ³ μ νλ©΄ μ μ λ‘ μ΄λ€ μ¨λ²μΈμ§ μ νλλ©΄ μ’κ² μ
- μκ°μ΄ μ€λ 걸리λ κ²½μ° μμ
- μ¬μ§μ μ¬λ¬μ₯ μ¬λ¦΄ λ λ€μ€ μ νμ΄ κ°λ₯νλ©΄ μ’κ² μ
곡μ μ¨λ²
- 곡μ μ¨λ²μ λ§λ€κ³ μ¬μ©μλ₯Ό μ΄λνλ©΄ μ¬μ§μ κ°μ΄ λ³Ό μ μλ€λ κ² μ¬λ°λ λΆλΆμΈ κ±° κ°μ
- 곡μ μ¨λ²μ λ§λ€ λ, μ¬μ©μλ₯Ό μ΄λν΄μΌλ§ 곡μ μ¨λ²(ν)μ μ¨λ²μ΄ μκΈ°λ κ²μ λͺ°λμ. μ€λͺ μ΄ νμν κ² κ°μ
κΈ°ν
μ λ‘λ λͺ¨λ¬μμ κΈ°κΈ°μ λ€λ‘κ°κΈ°λ₯Ό λλ₯΄λ©΄ μ΄νμ΄ μ’ λ£λλ νμμ΄ λνλ¨ -> AndroidManifest.xmlμμ λλ μ§μνμ§ μλ μμ±μ μ κ±°ν ν ν΄κ²°λ¨832a5ab- μ±μ€ν μ΄λ‘λ μ€μΉνκ³ μΆμ
- 곡μ μ¨λ²μ λ°μμ λ¨κΈΈ μ μμΌλ©΄ μ’κ² μ. μ’μμ νΉμ μ€ν°μ»€. λ€μν μ€ν°μ»€λ₯Ό ν맀νμΌλ©΄ μ’κ² μ
- 곡μ λ°μ μ¨λ²μ μ¬μ§μ μ¬λ¦¬κ³ μΆμ
- μ¬μ§ 보μ λ ν μ μμΌλ©΄ μ’κ² μ. λ°κΈ° μ‘°μ , μ±λ μ‘°μ λ±
- μ λ‘λ λ μ§λ νμ¬ μλμΌλ‘ μ μ₯λλλ°, μ§μ μμ κ°λ₯νλ©΄ μ’κ² μ
곡μ κΈ°λ₯ κ°λ°μ μν΄ Firebase Admin SDKκ° νμνμ.
λ°λΌμ Node.js νκ²½μμ ꡬλλκ³ , μ΄κΈ° λ‘λ© μλ κ°μ λ κΈ°λν μ μλ Next.jsλ‘ Migrationν¨
μ¨λ² 곡μ (μ κΈ°λ₯)
κ²μλ¬Ό μ λ‘λ λͺ¨λ¬
- κΈ°μ‘΄: μ¬μ§ μ ν λ° μ 체 μ¬μ ν κ°λ₯
- κ°μ : μ¬μ§ μ ν ν, μΌλΆ μμ λ° μΆκ° μ ν κ°λ₯
![]() |
π | ![]() |
v1 | v2 |
6. μ μ νΌλλ°±μ μ°Έκ³ ν΄μ£ΌμΈμ :)
Firestore Database
// {uid}/{uid}
{
sharedAlbums: Reference(albumDoc){}
}
// {uid}/{uid}/album/{albumId}
{
createdTime: Timestamp;
feedList: String(feedId)[];
name: String;
sharedUsers: {uid:String; permission: "read"}[];
}
// {uid}/{uid}/feed/{feedId}
{
id: String;
title: String;
text: String;
seletedAddress: String;
emotionImage: String;
weatherImage: String;
timestamp: Timestamp;
}
Storage
feed/{feedId + imageIndex}.{νμ₯μ}
profile/{uid}.{νμ₯μ}