구현 목표모든 사용자들에게 동일하게 전송되는 알림이 있는데,설정 화면에서 각각의 알림을 개별적으로 On/Off 할 수 있도록 구현해 보았다. Token과 Topic의 차이점FCM(Firebase Cloud Messaging)을 통해 사용자가 알림을 수신하는 방식에는 대표적으로 두 가지가 있다.Token 방식: 특정 사용자에게만 알림을 보낼 때 사용Topic 방식: 다수의 사용자에게 동일한 알림을 보낼 때 사용 항목 Token Topic대상단일 기기 (1:1)여러 기기 (그룹)사용 목적사용자마다 다른 알림 전송동일한 알림을 다수에게 전송사용 예시 1:1 메시지, 주문 상태 등 이벤트, 공지 등전송 방식개별 토큰으로 전송topic으로 전송유지 조건앱 삭제·재설치 시 토큰 변경될 수 있음구독 취소 전까지 유지..
구현 목표사용자가 알림을 클릭했을 때, 지정된 웹 링크로 이동하는 기능을 구현한다. FCM 메시지 수신 시 기기 상태상태설명Foreground앱이 켜져 있고 사용자에게 보여지고 있는 상태Background앱은 실행 중이지만 백그라운드로 전환된 상태 (예: 홈 버튼 누름)Terminated앱이 완전히 종료된 상태각 상태에 따라 알림 수신 및 처리 방식이 다르므로, 상태에 맞는 코드를 구현해야 한다. 기본 설정기본적인 FCM 연동 방법은 다음 글을 참고한다. [Flutter] Android에서 FCM 연동(1) - 푸시 알림 수신 테스트 flutter pub add url_launcher`url_launcher` 패키지를 설치한다. import 'package:url_launcher/url_launche..
앱이 Android 15(API수준 35) 이상을 타겟팅해야 함얼마 전에 구글플레이에서 다음과 같은 메일을 받았다. 콘솔에서 더 자세히 확인해 봤더니 2025년 8월 31일까지프로덕션 앱을 안드로이드 15 (API 수준 35) 이상을 타겟팅하지 않으면더 이상 앱을 업데이트할 수 없다고 한다. flutterCompileSdkVersion = '35'flutterTargetSdkVersion = '35'그래서 기존 `34`였던 sdk 버전을 `35`로 올리고 앱을 다시 게시했다. Android 15 Edge-to-edge버전 업데이트 후 기능이 잘 작동하는지 이것저것 확인해 보던 중Bottom sheet를 올렸을 때 화면 하단의 내비게이션바와 앱 화면이 겹치는 것을 확인했다. 사용자들이 텍스트를 확인하거나 ..
구현 목표플러터로 만든 안드로이드 앱에서 매일 특정 시간에 DB를 조회해서조건 충족 시 푸시 알림을 보내는 기능을 구현해보려고 한다. 우선 이전 글에서 Flutter와 Firebase 기초 연동까지 구현했다. [Flutter] Android 앱에 Firebase 연동 기초 설정Firebase 프로젝트 생성 및 앱 등록Firebase에서 프로젝트를 생성하고 안드로이드 앱을 등록하면 `google-services.josn` 파일을 다운 받을 수 있다.이 파일을 `android\app\google-services.json` 디렉토리로 이동한divheer.tistory.com 이번에는 FCM 토큰을 등록해서 알림을 수신할 수 있도록 간단하게 테스트를 해 보자. FCM 메시지 수신 시 기기 상태상태설명Foregr..
Firebase 프로젝트 생성 및 앱 등록Firebase에서 프로젝트를 생성하고 안드로이드 앱을 등록하면 `google-services.josn` 파일을 다운 받을 수 있다.이 파일을 `android\app\google-services.json` 디렉토리로 이동한다.민감할 수 있는 정보들이 들어있기 때문에 나는 이 파일을 `.gitignore`에 추가했다. Flutter 앱에 Firebase 추가필수 CLI 도구 설치npm install -g firebase-toolsFirebase CLI를 설치한다. firebase login다음 명령어를 실행하여 Google 계정으로 Firebase에 로그인한다. dart pub global activate flutterfire_cli디렉터리에서 다음 명령어를 실행하..
리뷰 요청 기능을 추가한 이유앱 출시 후 약 6개월이 지났지만, 아직 앱 스토어에 작성된 리뷰가 없다.리뷰가 하나라도 있으면 앱의 신뢰도를 높이는 데 도움이 될 것 같다는 생각이 들었다.그래서 앱 내에 리뷰 요청 기능을 추가해서 적극적으로 리뷰 작성을 유도하기로 했다. 리뷰를 요청하는 두 가지 방법인앱 리뷰 API 사용하기안드로이드와 iOS 모두 인앱 리뷰를 요청할 수 있는 API를 제공한다.UI를 따로 구성할 필요가 없기 때문에 가장 간단하게 구현할 수 있는 방식이지만OS별로 제한사항이 많기 때문에, 사용자 경험을 커스터마이징 하기 어렵다. 앱은 사용자에게 평점 버튼 또는 카드를 표시하기 전이나 표시하는 동안 사용자 의견 관련 질문 (예: '앱이 마음에 드십니까?') 또는 예측 질문 (예: '이 앱을 ..
`print()`로 로그를 출력하면 다음과 같은 경고 메세지가 뜬다. 지금까지는 이 메세지를 그냥 무시해 왔는데 앱을 배포하기 위해서는 릴리즈 모드에서 로그가 출력되지 않도록 할 필요성을 느꼈다. 프로덕션 코드에서는 print() 호출을 피해라DO avoid `print` calls in production code.For production code, consider using a logging framework. If you are using Flutter, you can use `debugPrint` or surround `print` calls with a check for `kDebugMode`다트 공식문서에서 프로덕션 코드에서는 `print()`를 피하라는 경고와 함께, 로그를 출력할 다른 방..
앱 실행 중에 마지막 스택에서 뒤로 가기 버튼을 누르면 "뒤로 가기를 한 번 더 누르시면 종료됩니다"라는 내용의 스낵바가 뜨는 기능을 구현해 보자. PopSope 위젯 추가하기DateTime? backPressedTime;@overrideWidget build(BuildContext context) { return PopScope( canPop: false, onPopInvoked: (bool didPop) { if (didPop) { return; } DateTime nowTime = DateTime.now(); if (backPressedTime == null || nowTime.differ..
프로덕션 앱 심사 거절무려 3번의 리젝 끝에 드디어 정식으로 앱이 출시되었다.플레이스토어 심사 거절 사례와 해결 방법을 공유한다. 한 번 게시 검토를 신청하면 답변까지 보통 4일이 걸린다.나는 첫 게시 신청을 한 게 11월 15일이었고, 세 번의 리젝 끝에 프로덕션 앱이 출시된 게 11월 24일이었다. 리젝 사유는 이메일로 받기도 하고, 구글 플레이 콘솔 `정책 상태` 항목에서도 확인할 수 있다.리젝 사유는 인앱 경험 스크린샷까지 첨부해서 친절하게 알려주는 편이다. 첫 번째 리젝: 혼동을 야기하는 주장 정책 위반2024년 11월 15일 밤 11시에 처음으로 프로덕션 게시 신청을 했는데2024년 11월 19일 오전 9시에 리젝 메일을 받았다. 앱에 혼동을 야기하는 주장 관련 정책을 준수하지 않는 콘텐츠가..
[Flutter] S3 버킷에 업로드한 파일 삭제하기단일 객체 삭제 방법은 상단의 글을 참고하고, 이번에는 여러 객체를 한 번에 삭제하는 방법을 알아보자. Lambda 함수 생성import { S3Client, DeleteObjectsCommand } from "@aws-sdk/client-s3";const s3Client = new S3Client({ region: 'ap-northeast-2' });export const handler = async (event) => { // body에 JSON.parse 하면 에러 발생함 const { objectKeys } = event.body; if (!objectKeys) { return { statusCod..