通过Firebase从Android设备发送推送通知

时间:2020-09-05 21:22:46

标签: android firebase push-notification retrofit okhttp

我有兴趣通过Firebase从Android应用发送推送通知。 Firebase文档指出,有效负载json必须发送到https://fcm.googleapis.com/fcm/send

因此,我与Retrofit一起使用来发送json,但请求失败,如果我发送的请求没有进行Retrofit,则效果很好。

两个实施之间有什么区别,为什么它不能与Retrofit一起使用。

以下是这两种实现方式,以及使用Retrofit时的错误。

val notificationBody = NotificationBody(notificationData, "/topics/all")
    val rb = Gson().toJson(notificationBody).toRequestBody("application/json".toMediaTypeOrNull())
    val responeNoti = RetrofitManager.notificationServiceApi.postNotification(rb)
    responeNoti.enqueue(object : Callback<ResponseBody>{
        override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
            Log.d(TAG, t.message)
        }

        override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
            Log.d(TAG, response.toString())
        }

    })

NotificationServiceApi

 private const val FCM_URL = "https://fcm.googleapis.com/fcm/"
val notificationServiceApi: ServiceApi by lazy{
        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        val okHttpClientBuilder = OkHttpClient.Builder()
        okHttpClientBuilder.addInterceptor(object : Interceptor{
            override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
                val request: Request = chain.request().newBuilder().
                addHeader("Content-Type", "application/json").
                addHeader("Authorization","key=*my firebase key*").build()

                return chain.proceed(request)
            }
        }).addInterceptor(interceptor)

        val notificationRetrofit = Retrofit.Builder()
            .client(okHttpClientBuilder.build())
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl(FCM_URL)
            .build()
        notificationRetrofit.create(ServiceApi::class.java)
    }

ServiceApi

@POST("send/")
fun postNotification(@Body notificationBody: RequestBody) : Call<ResponseBody>

日志Http

2020-09-06 00:12:27.991 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: --> POST 
        https://fcm.googleapis.com/fcm/send/
2020-09-06 00:12:27.991 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: Content- 
Length: 117
    2020-09-06 00:12:27.991 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: Content-Type: application/json
    2020-09-06 00:12:27.991 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: Authorization: key=my firebase key
    2020-09-06 00:12:27.991 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: {"data":{"imageUrl":"https://i.imgur.com/KA1jrU7.jpg","textBody":"my content","title":"my title"},"to":"/topics/all"}
    2020-09-06 00:12:27.991 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: --> END POST (117-byte body)
    2020-09-06 00:12:29.198 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: <-- 404 https://fcm.googleapis.com/fcm/send/ (1206ms)
    2020-09-06 00:12:29.198 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: content-type: text/plain; charset=utf-8
    2020-09-06 00:12:29.198 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: x-content-type-options: nosniff
    2020-09-06 00:12:29.198 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: x-frame-options: SAMEORIGIN
    2020-09-06 00:12:29.198 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: x-xss-protection: 0
    2020-09-06 00:12:29.198 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: date: Sat, 05 Sep 2020 21:12:29 GMT
    2020-09-06 00:12:29.198 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: content-length: 135
    2020-09-06 00:12:29.198 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: alt-svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
    2020-09-06 00:12:29.199 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: A valid push subscription endpoint should be specified in the URL as such: https://fcm.googleapis.com/wp/dHIoDxE7Hdg:APA91bH1Zj0kNa...
    2020-09-06 00:12:29.199 32059-32244/com.bagi.soreknetmanager I/okhttp.OkHttpClient: <-- END HTTP (135-byte body)
    2020-09-06 00:12:29.201 32059-32059/com.bagi.soreknetmanager D/MainActivity: Response{protocol=h2, code=404, message=, url=https://fcm.googleapis.com/fcm/send/}

在不使用翻新的情况下效果很好的实现方式

 val notificationBody = NotificationBody(notificationData, "/topics/all")
    val jsonPayload = createJsonFromObject(notificationBody)
     val thread = Thread(Runnable {
    try {
        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        var client = OkHttpClient().newBuilder().addInterceptor(interceptor)
            .build()
        var mediaType = "application/json".toMediaTypeOrNull()
        var body: RequestBody = RequestBody.create(
            mediaType,
            jsonPayload
        )
        var request: Request = Request.Builder()
            .url("https://fcm.googleapis.com/fcm/send")
            .method("POST", body)
            .addHeader("Content-Type", "application/json")
            .addHeader(
                "Authorization",
                "key=my firebase key"
            )
            .build()
        var response: okhttp3.Response = client.newCall(request).execute()
    } catch (e: Exception) {
        e.printStackTrace()
    }
})

thread.start()

1 个答案:

答案 0 :(得分:0)

您的网址中有错误。 检查您的FCM_URL,它不完整,您忘记附加“发送”一词

FCM_URL = "https://fcm.googleapis.com/fcm/"

正确的网址-

FCM_URL ="https://fcm.googleapis.com/fcm/send"