[#270 푸시 알람 배지가 앱 아이콘에 뜨도록 구현한다#271
Conversation
opficdev
commented
Mar 13, 2026
- closed 푸시 알람 배지가 앱 아이콘에 뜨도록 구현한다 #270
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 이 PR은 앱 아이콘에 푸시 알림 배지가 표시되도록 기능을 구현합니다. 앱 내에서 읽지 않은 알림 수를 Firebase Firestore와 동기화하고, 새로운 푸시 알림이 전송될 때마다 클라우드 함수에서 현재 읽지 않은 알림 수를 계산하여 APNs 페이로드에 포함시킴으로써 앱 아이콘 배지가 자동으로 업데이트되도록 합니다. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
이번 PR은 푸시 알림 수신 시 앱 아이콘에 배지를 표시하는 기능을 구현합니다. AppDelegate.swift에서는 사용자 인증 상태를 감지하고, 로그인된 사용자에 대해 Firestore의 읽지 않은 알림 수를 관찰하여 앱 아이콘 배지를 동기화하는 로직이 추가되었습니다. Firebase 함수(notification.ts)에서는 푸시 알림을 보낼 때 읽지 않은 알림 수를 함께 조회하여 APNs 페이로드에 포함하도록 수정되었습니다. 전반적으로 클라이언트 측 동기화와 서버 측 푸시 페이로드 수정이 잘 이루어졌습니다. 코드의 안정성과 가독성을 높이기 위해 AppDelegate.swift 파일에 몇 가지 개선 사항을 제안합니다.
| class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate { | ||
| private let logger = Logger(category: "AppDelegate") | ||
| private var store: Firestore { Firestore.firestore() } | ||
| private var authStateListenerHandle: AuthStateDidChangeListenerHandle? |
There was a problem hiding this comment.
| func startObservingBadgeCount() { | ||
| cancellable = try? observeUnreadNotificationCount() | ||
| .receive(on: DispatchQueue.main) | ||
| .sink( | ||
| receiveCompletion: { [weak self] completion in | ||
| guard let self else { return } | ||
|
|
||
| if case .failure(let error) = completion { | ||
| self.logger.error("Failed to observe unread notification count", error: error) | ||
| } | ||
| }, | ||
| receiveValue: { [weak self] count in | ||
| self?.updateBadgeCount(count) | ||
| } | ||
| ) | ||
| } |
There was a problem hiding this comment.
startObservingBadgeCount() 함수에서 try?를 사용하여 observeUnreadNotificationCount()에서 발생하는 오류를 암묵적으로 무시하고 있습니다. observeUnreadNotificationCount()는 사용자가 인증되지 않은 경우 오류를 발생시킬 수 있으며, 이 경우 cancellable은 nil이 되고 아무런 동작도 하지 않게 됩니다. 오류가 발생할 가능성이 있는 경우, do-catch 구문을 사용하여 명시적으로 오류를 처리하고 로그를 남기는 것이 더 안전한 방법입니다.
func startObservingBadgeCount() {
do {
cancellable = try observeUnreadNotificationCount()
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { [weak self] completion in
guard let self else { return }
if case .failure(let error) = completion {
self.logger.error("Failed to observe unread notification count", error: error)
}
},
receiveValue: { [weak self] count in
self?.updateBadgeCount(count)
}
)
} catch {
logger.error("Failed to start observing badge count", error: error)
}
}| .addSnapshotListener { [weak self] snapshot, error in | ||
| if let error { | ||
| self?.logger.error("Failed to observe unread notification count", error: error) | ||
| subject.send(completion: .failure(error)) | ||
| return | ||
| } | ||
|
|
||
| guard let snapshot else { return } | ||
|
|
||
| let unreadNotificationCount = snapshot.documents.count | ||
| self?.logger.info("Observed unread notification count: \(unreadNotificationCount)") | ||
| subject.send(unreadNotificationCount) | ||
| } |
There was a problem hiding this comment.
addSnapshotListener의 클로저 내에서 self?를 여러 번 사용하고 있습니다. 클로저 시작 부분에서 guard let self = self else { return }을 사용하여 self를 안전하게 언래핑하면 코드가 더 간결해지고, 클로저 실행 동안 self가 nil이 되지 않음을 보장할 수 있습니다.
.addSnapshotListener { [weak self] snapshot, error in
guard let self else { return }
if let error {
self.logger.error("Failed to observe unread notification count", error: error)
subject.send(completion: .failure(error))
return
}
guard let snapshot else { return }
let unreadNotificationCount = snapshot.documents.count
self.logger.info("Observed unread notification count: \(unreadNotificationCount)")
subject.send(unreadNotificationCount)
}