[FCM] FirebaseCloudMessaging API 만들기
이번엔 메시지 API를 만들어서 Postman을 통해 토큰과 타이틀, 바디를 보내 폰으로 알림을 받는 과정을 정리해보려 합니다. Firebase프로젝트를 생성하는 과정은 이전 게시글을 참고하시면 됩니다. [F
huzit.tistory.com
[FCM]Firebase Cloud Messaging 수신하기
Android에서 Firebase 클라우드 메시징 클라이언트 앱 설정 Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보
huzit.tistory.com
메시지 수신과 RestAPI는 이전 게시글에서 볼 수 있습니다.
만들어야 할 것은 클래스 3개 인터페이스 1개입니다.
시작해봅시다.
Retrofit2 의존성 추가
Retrofit
A type-safe HTTP client for Android and Java
square.github.io
//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
//Object -> JSON
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//Response를 String받기위함
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
GsonConverter를 안 넣으면
java.lang.IllegalArgumentException: Unable to create @Body converter for class com.example.isyousleep_client.dto.Message (parameter #1)
에러를 뱉어냅니다. JSON으로 변경할 컨버터가 없다고 합니다.
SclarsConverter는 응답을 JSON이 아니라 String으로 변경해줍니다. 저게 왜 있나 곰곰이 생각해 보니 정리 못한 코드였네요 ㅎㅎ. 설계도 없이 만든 어플이라 처음에 기능을 막 넣다가 뺐는데 의존성은 생각 못했네요. 알고 있으면 좋은 컨버터입니다.
Message 클래스 생성
data class Message(
var targetToken: String = "",
var title: String = "",
var body: String = "",
){}
API에 Post로 보내야 하므로 RequestBody로 지정한 DTO와 똑같은 data class를 생성해줍니다.
RetorfitInstance 생성
class RetrofitClientInstance {
fun callHwan(BaseUrl: String): Retrofit {
val okhttp = OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS).build()
return Retrofit
.Builder()
.baseUrl(BaseUrl)
.client(okhttp)
// .addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
.build()
}
}
공식 홈페이지와 다른 코드는 딱 2줄입니다.
클라이언트로 okhttp 객체를 하나 넣어줬습니다. 원래 타임아웃이 10초로 설정돼있는데 30초로 늘리는 목적입니다.
addConverFactory에 GsonConverterFactory를 넣어줍니다. 패러미터로 Gson객체를 요구하므로 넣어줍니다.
API Request Method 생성
interface GetDataService {
@GET("/{testValue}")
fun retrofitTest(@Path("testValue") test: String): Call<String>
@POST("/sendNotification")
fun sendNoti(@Body notiMessage: Message): Call<Void>
}
인터페이스입니다. 함수 명은 독자적으로 생성해도 되지만 패러미터는 받는 쪽의 타입과 맞춰줘야 합니다. requestBody로 받는 경우 @Body 어노테이션을 선언해줘야 합니다. DTO명은 같지 않아도 되지만 프로퍼티는 동일해야 합니다.
레이아웃
간단하게 버튼 하나만 추가합니다. 이미지 버튼을 썼지만 그냥 버튼 쓰셔도 문제없습니다.
실제 통신 (MainActivity)
호출 함수
private fun callHwanForMassage(msg: Message){
val baseUrl: String = if(checkInternet()){
//집 라우터 IP
BASE_URL_1
}else{
//개인 공유기 IP
BASE_URL_2
}
//GetDataService의 sendNoti 생성
val callHwan = RetrofitClientInstance().callHwan(baseUrl).create(GetDataService::class.java).sendNoti(msg)
callHwan.enqueue(object : Callback<Void> {
override fun onResponse(call: Call<Void>, response: Response<Void>) {
Log.d("test", "알림 성공 ${response.body()}")
}
override fun onFailure(call: Call<Void>, t: Throwable) {
Log.d("test", "알림 실패 ${t.message}")
}
})
}
baseUrl은 "서버 IP:포트"를 넣어주면 됩니다.
제 경우는 방에서 쓰는 공유기와 집으로 들어오는 라우터 2대가 있습니다.
방에서 쓰는 공유기는 와이파이 환경에서 통신할 목적이고, 집으로 들어오는 라우터는 데이터 환경에서 통신할 목적이므로 2가지를 구분하도록 짰습니다.
이후 Builder패턴으로 RetrofitInstance 객체를 생성해서 인터페이스에 선언한 함수 sendNoti를 생성해줍니다.
enqueue로 통신을 시작하고 패러미터로 콜백을 줘야 하는데 익명 객체로 콜백을 줍니다.
콜백 상태에 따라 로그를 출력하도록 작성합니다.
onCreate()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val message = Message(
getString(R.string.myPhoneToken),
"test",
"testMessage"
)
binding.callHwan.setOnClickListener {
Thread {
callHwanForMassage(message)
}.start()
}
}
메시지 객체를 만들어서 버튼이 눌릴 때마다 호출하도록 짰습니다.
버튼 안에 스레드를 만들어준 이유는 통신이 완료될 때까지 기다리면 안 된다 생각해서 때문에 만들어줬습니다. 사실 기능이 버튼을 눌러서 호출하는 거 하나뿐이라 스레드 안 만들어줘도 통신됩니다.
결과
정상적으로 알림 메시지가 온 것을 볼 수 있습니다.
'안드로이드 > Firebase' 카테고리의 다른 글
Firebase Crashlytics 시작하기 (0) | 2023.04.14 |
---|---|
Firebase 시작하기 (0) | 2023.04.14 |
[FCM] FirebaseCloudMessaging API 만들기 (1) | 2022.11.12 |
[FCM]Firebase Cloud Messaging 수신하기 (0) | 2022.11.11 |
파이어베이스로 구글 소셜로그인 (0) | 2022.06.13 |