드디어!!!!! 따북에 정해진 시간마다 책 구절을 보내줄 서버를 구현할 수 있게 되었다!!!!
기쁜 마음으로 포스팅을 해본다~~
implementation("com.google.firebase:firebase-admin:7.1.0")
스프링에서 firebase를 사용할 수 있도록 디펜던시를 추가 해 준다.
다음은 설정파일이다.
@Configuration
class ScheduledConfig {
private val POOL_SIZE = 10
fun scheduler(): TaskScheduler {
val scheduler = ThreadPoolTaskScheduler()
scheduler.poolSize = POOL_SIZE
return scheduler
}
}
POOL_SIZE는 한 번에 처리할 수 있는 메세지 수라고 하는데 10개로 지정 해 두었다. 사용자가 그렇게 많지 않아서 상관 없을 것 같다^^ 나중에 사용자 수가 많아지면 늘려야지..
그리고 설정파일이므로 Configuration 어노테이션을 꼭 붙여줘야한다. 경험상 이 어노테이션이 없으면 작동하지 않았다.
data class NotificationMessage(
val title: String,
val message: String
)
역시나 data class로 구현했고 제목과 메세지를 담도록 했다. 찾아보니 파이어베이스에서 보낼 수 있는 메세지 형식이 있는데 제목과 본문이 필요했다.
@Service
class NotificationScheduler (
private val bookCommandService: BookCommandService
) {
private var instance: FirebaseMessaging? = null
@PostConstruct
@Throws(IOException::class)
fun firebaseSetting() {
val googleCredentials =
GoogleCredentials.fromStream(ClassPathResource("firebase/어쩌구저쩌구.json").inputStream)
.createScoped(listOf("https://www.googleapis.com/auth/firebase.messaging"))
val secondaryAppConfig = FirebaseOptions.builder()
.setCredentials(googleCredentials)
.build()
val app = FirebaseApp.initializeApp(secondaryAppConfig)
instance = FirebaseMessaging.getInstance(app)
}
fun getRandomMessage(): NotificationMessage {
val title = "${bookCommandService.getRandomBookNoAuth().title}_${bookCommandService.getRandomBookNoAuth().author}"
val message = bookCommandService.getRandomBookNoAuth().content
return NotificationMessage(title, message)
}
@Scheduled(cron = "0 0 08 * * ?")
@Throws(FirebaseMessagingException::class)
fun pushMorningAlarm() {
pushAlarm(getRandomMessage())
}
@Scheduled(cron = "0 0 13 * * ?")
@Throws(FirebaseMessagingException::class)
fun pushLunchAlarm() {
pushAlarm(getRandomMessage())
}
@Scheduled(cron = "0 00 19 * * ?")
@Throws(FirebaseMessagingException::class)
fun pushDinnerAlarm() {
pushAlarm(getRandomMessage())
}
@Throws(FirebaseMessagingException::class)
fun pushAlarm(data: NotificationMessage) {
val message = getMessage(data)
sendMessage(message)
}
fun getMessage(data: NotificationMessage): Message {
val notification = Notification.builder().setTitle(data.title).setBody(data.message).build()
val builder = Message.builder()
val topic = "토픽명"
return builder.setTopic(topic).setNotification(notification).build()
}
@Throws(FirebaseMessagingException::class)
fun sendMessage(message: Message?): String? {
return instance!!.send(message)
}
}
대망의 파이어베이스 서비스를 구동시킬 부분이다. 서비스이므로 Service 어노테이션을 붙여준다.
Firebase 비공개 키를 생성해야 한다.
위 이미지처럼 비공개 키 파일을 생성하는데 자바로 생성 해 준다.
다음은 원하는 디렉토리에 넣어주면 되는데, 나는 API 모듈의 resource부분에 디렉토리를 따로 만들어 넣어주었다.
알림을 보내는 방식은 토큰방식과 토픽방식이 있다고 하는데 나는 참고한 포스팅처럼 토픽방식을 채택했다.
토큰방식은 db에 사용자별 토큰을 저장하고, 그 값을 불러와 비교해야하는데 로직이 복잡해지므로 토픽방식을 추천한다.
파이어베이스 토픽은 앱이 구동될 때 생성되어 알림을 보낼 때 토픽을 체크해 해당 토픽을 가진 앱이 있으면 그 앱들에게 알림을 보내는 방식으로 구현된다.
따라서 안드로이드 스튜디오 앱이 켜질 때 onCreate 하위에
FirebaseMessaging.getInstance().subscribeToTopic("토픽명");
을 기재 해 줘야한다.
위에서부터 살펴보면 GoogleCredentials.fromStream
구문을 통해 파이어베이스에 접속하고
Scheduled
어노테이션을 통해 주기적으로, 내가 cron 형식으로 정해 준 시간마다 특정 메서드를 실행하도록 한다. 물론 여기서는 푸시 알림을 보낸다.
getRandomMessage
구절은 따북 프로젝트에서 랜덤으로 책 내용을 찾아주는 기능이므로 원하는 로직을 작성 해 주면 되겠다.
@EnableScheduling
@ConfigurationPropertiesScan
@SpringBootApplication(
scanBasePackages = ["kr.co.book.list.domain", "kr.co.book.list.lib", "kr.co.book.list.api"]
)
class ApiApplication
fun main(args: Array<String>) {
runApplication<ApiApplication>(*args)
}
스프링 부트를 실행할 때 @EnableScheduling
어노테이션이 필요하다. 이 어노테이션이 붙어있어야 스케줄링이 가능해진다.
이제 출근길 8시, 점심먹고 1시, 저녁먹고 7시에 다른 사람들이 작성한 예쁜 책 내용을 푸시 알림으로 받을 수 있다~~ 야호~~
오 멋있습니다👍👍