Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

모바일 앱(안드로이드)

Jetpack Compose + Firebase 기반 게시판 앱 개발기

Billcorea 2025. 7. 1. 15:20
반응형

 

Jetpack Compose + Firebase 기반 게시판 앱 개발기

게시글 만들기

 

이 글은 Jetpack Compose, Firebase Realtime Database, Hilt, Compose Destinations를 기반으로 한 게시판 앱 개발 과정을 정리한 것입니다. 게시글은 최근순으로 표시되며, 댓글 기능도 포함합니다.

1. 프로젝트 구성

  • Kotlin
  • Jetpack Compose
  • Firebase Realtime Database
  • Hilt (DI)
  • Compose Destinations (Navigation)

2. 게시글 리스트 화면

Firebase에서 게시글 데이터를 읽고, 최근 등록순으로 보여줍니다.


LazyColumn(
    reverseLayout = true // 최신 글이 위로
) {
    items(posts) { post ->
        PostItem(post)
    }
}

FloatingActionButton을 이용해 글쓰기 화면으로 이동합니다.


Scaffold(
    floatingActionButton = {
        FloatingActionButton(onClick = {
            navigator.navigate(NewPostScreenDestination())
        }) {
            Icon(Icons.Default.Add, contentDescription = "새 글 작성")
        }
    }
) {
    // Content here
}

3. 글쓰기 화면


@Destination
@Composable
fun NewPostScreen(navigator: DestinationsNavigator) {
    var title by remember { mutableStateOf("") }
    var content by remember { mutableStateOf("") }

    Column(modifier = Modifier.padding(16.dp)) {
        OutlinedTextField(
            value = title,
            onValueChange = { title = it },
            label = { Text("제목") },
            colors = TextFieldDefaults.outlinedTextFieldColors(
                textColor = Color.Black
            )
        )
        Spacer(Modifier.height(8.dp))
        OutlinedTextField(
            value = content,
            onValueChange = { content = it },
            label = { Text("내용") }
        )
        Spacer(Modifier.height(16.dp))
        Button(onClick = {
            // Firebase에 저장
            navigator.popBackStack()
        }) {
            Text("등록")
        }
    }
}

4. 게시글 수정

수정 시, postId를 인자로 전달해 해당 글을 로딩하고 수정합니다.


@Destination
@Composable
fun EditPostScreen(postId: String, navigator: DestinationsNavigator) {
    val viewModel: PostViewModel = hiltViewModel()
    val post = viewModel.getPost(postId)

    // 수정 UI 구성
}

5. Compose Destinations 구성


@Composable
fun MainNavHost() {
    val navController = rememberNavController()
    DestinationsNavHost(
        navController = navController,
        navGraph = NavGraphs.root
    )
}

Destinations에서 ViewModel 외부 주입이 필요한 경우


DestinationsNavHost(navController = navController, navGraph = NavGraphs.root) {
    composable(EditPostScreenDestination) {
        EditPostScreen(
            postId = it.navArgs.postId,
            navigator = it.destinationsNavigator,
            mainViewModel = customViewModel
        )
    }
}

6. UI 요소 조정

  • TopBar 여백 제거: Scaffold에서 topBar 생략
  • FloatingActionButton 아래 배치: Scaffold 내에서 기본 위치에 둬도 하단 고정
  • ModalBottomSheet 테두리 색상 조정: 직접 설정은 어려움 → 커스텀 구현 필요

7. 다국어 번역 예시

용어 번역
Posts 한국어: 게시글, 중국어: 帖子, 대만어: 貼文, 일본어: 投稿, 베트남어: Bài viết, 태국어: โพสต์, 필리핀어: Mga post
도로명주소 영어: Road name address, 중국어: 道路名地址, 대만어: 路名地址, 일본어: 道路名住所, 베트남어: Địa chỉ theo tên đường, 태국어: ที่อยู่ตามชื่อถนน, 필리핀어: Address ng kalsada
Distance 중국어: 距离, 대만어: 距離, 일본어: 距離, 베트남어: Khoảng cách, 태국어: ระยะทาง, 필리핀어: Distansya

마무리

이와 같은 구조로 Jetpack Compose와 Firebase를 이용한 게시판 앱을 확장할 수 있습니다. 다음 포스트에서는 이미지 업로드, 사용자 인증, 또는 푸시 알림 추가도 소개할 수 있습니다.

반응형