푸시 알람
좋아요, 팔로우, 댓글이 눌렸을 때 푸시 알람을 발송하는 기능을 구현하며 프로젝트를 마무리해보자.
푸시 알람은 서버 측에서 발송해야 한다. Firebase에 있는 fcm 기능을 이용하여 특정 계정, 프로젝트(앱)에 푸시를 전송할 수 있다.
pushDTO를 만들어 push에 대한 내용을 관리하자.
package com.example.firstapp.navigation.model
data class PushDTO(
var to: String? = null,
var notification: Notification = Notification()
){
data class Notification(
var body: String? = null,
var title: String? = null
)
}
위의 구조를 이용하여 프로젝트(앱)를 설치한 유저에게 푸시 알람을 보낼 수 있다.
하지만 특정한 유저에게 보내기 위해서는 유저의 uid와 token이 필요하다.
이를 등록하는 코드를 살펴보자.
fun registerPushToken(){
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
val token = task.result
val uid = FirebaseAuth.getInstance().currentUser?.uid
val map = mutableMapOf<String, Any>()
map["pushToken"] = token!!
FirebaseFirestore.getInstance().collection("pushTokens").document(uid!!).set(map)
}
}
firebaseMessaging라이브러리에서 token을 받아와 등록하면 된다.
기존에 사용하던 라이브러리는 deprecateddeprecated 되어 사용을 위의 라이브러리를 사용해야 한다.
그리고 위의 함수를 onCreate에 넣어 앱이 실행될 때 token을 등록하게 하자.
다음은 푸시 알람을 보내는 코드이다.
package com.example.firstapp.navigation.util
import android.util.Log
import com.example.firstapp.navigation.model.PushDTO
import com.google.firebase.firestore.FirebaseFirestore
import com.google.gson.Gson
import okhttp3.*
import serverKey
import java.io.IOException
class FcmPush{
var JSON = MediaType.parse("application/json; charset=utf-8")
var url = "https://fcm.googleapis.com/fcm/send"
var gson: Gson? = null
var okHttpClient: OkHttpClient? = null
companion object{
var instance = FcmPush()
}
init {
gson = Gson()
okHttpClient = OkHttpClient()
}
fun sendMessage(destinationUid: String, title: String, message: String){
Log.d("콜","실행")
FirebaseFirestore.getInstance().collection("pushTokens").document(destinationUid).get().addOnCompleteListener {
task ->
if(task.isSuccessful){
Log.d("콜","성공")
var token = task.result?.get("pushToken").toString()
var pushDTO = PushDTO()
pushDTO.to = token
pushDTO.notification.title = title
pushDTO.notification.body = message
var body = RequestBody.create(JSON, gson?.toJson(pushDTO))
var request = Request.Builder()
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "key="+serverKey)
.url(url)
.post(body)
.build()
okHttpClient?.newCall(request)?.enqueue(object: Callback{
override fun onFailure(call: Call?, e: IOException?) {
}
override fun onResponse(call: Call?, response: Response?) {
Log.d("콜","보냄")
println(response?.body()?.string())
}
})
}
}
}
}
gson과 okhttp라이브러리를 import 하여 onCreate에서 등록한 pushToken을 받아와 pushDTO에 할당한다.
그런 다음 body를 만들어 요청을 하는 구조이다. 이런 함수를 각 상황에 맞춰 사용하면 된다.
여기서 serverkey를 얻기 위해서는 다음 화면에 보이는 톱니바퀴를 눌러 serverkey를 확인할 수 있다.
다음은 함수 사용의 예이다.
fun favoriteAlarm(destinationUid: String){
var alarmDTO = AlarmDTO()
alarmDTO.destinationUid = destinationUid
alarmDTO.userId = FirebaseAuth.getInstance().currentUser?.email
alarmDTO.uid = FirebaseAuth.getInstance().currentUser?.uid
alarmDTO.kind = 0
alarmDTO.timestamp = System.currentTimeMillis()
FirebaseFirestore.getInstance().collection("alarms").document().set(alarmDTO)
var message = FirebaseAuth.getInstance()?.currentUser?.email + getString(R.string.alarm_favorite)
FcmPush.instance.sendMessage(destinationUid, "Instgram", message)
}
DetailFragment에서 좋아요 버튼이 눌렸을 때 현재 유저의 email을 받아와 좋아요가 눌린 계정에 알람을 보낸다.
fun commentAlarm(destinationUid: String, message: String){
var alarmDTO = AlarmDTO()
alarmDTO.destinationUid = destinationUid
alarmDTO.userId = FirebaseAuth.getInstance().currentUser?.email
alarmDTO.uid = FirebaseAuth.getInstance().currentUser?.uid
alarmDTO.kind = 1
alarmDTO.timestamp = System.currentTimeMillis()
alarmDTO.message = message
FirebaseFirestore.getInstance().collection("alarms").document().set(alarmDTO)
var message = FirebaseAuth.getInstance()?.currentUser?.email + getString(R.string.alarm_comment)
FcmPush.instance.sendMessage(destinationUid, "Instgram", message)
}
댓글이 달렸을 때 현재 유저의 email을 받아와 유저에게 알람을 보낸다.
fun followerAlarm(destinationUid: String){
var alarmDTO = AlarmDTO()
alarmDTO.destinationUid = destinationUid
alarmDTO.userId = auth?.currentUser?.email
alarmDTO.uid = auth?.currentUser?.uid
alarmDTO.kind = 2
alarmDTO.timestamp = System.currentTimeMillis()
FirebaseFirestore.getInstance().collection("alarms").document().set(alarmDTO)
var message = auth?.currentUser?.email + getString(R.string.alarm_follow)
FcmPush.instance.sendMessage(destinationUid, "Instgram", message)
}
팔로우가 눌렸을 때도 마찬가지로 동작한다.