如何在Android Studio(Java)中通过FCM程序化发送通知?
管理员端Android应用(Java)通过FCM程序化发送通知实现方案
一、前置准备
- 管理员端、用户端APP均完成FCM接入:在Firebase控制台添加两个应用,将各自的
google-services.json放入项目app/目录,确保build.gradle中引入com.google.firebase:firebase-messaging依赖。 - 获取FCM服务器密钥:Firebase控制台→项目设置→云消息传递→服务器密钥,注意:此密钥绝对不能硬编码到Android客户端代码中,生产环境必须通过自有后端中转调用FCM API。
- 用户端设备令牌获取与存储:用户端启动时调用
FirebaseMessaging.getInstance().getToken()获取设备令牌,上传至你们的数据库或管理员端可访问的存储,作为通知发送的目标标识。
二、标准生产方案(后端中转)
直接在Android客户端调用FCM API会泄露服务器密钥,引发安全风险,标准流程如下:
- 管理员端APP将通知内容、目标用户令牌发送至自有后端接口。
- 后端接口使用服务器密钥调用FCM HTTP API完成推送。
后端示例(Java Spring Boot)
import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; public class FcmNotificationSender { private static final String FCM_API_ENDPOINT = "https://fcm.googleapis.com/fcm/send"; private static final String FCM_SERVER_KEY = "你的FCM服务器密钥"; public static void pushNotification(String targetToken, String title, String content) { RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("Authorization", "key=" + FCM_SERVER_KEY); // 构建FCM请求体,可自定义data字段传递业务数据 String requestBody = String.format("{" + "\"to\": \"%s\"," + "\"notification\": {" + "\"title\": \"%s\"," + "\"body\": \"%s\"" + "}," + "\"data\": {" + "\"type\": \"admin_notify\"" + "}" + "}", targetToken, title, content); HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers); restTemplate.postForObject(FCM_API_ENDPOINT, requestEntity, String.class); } }
管理员端APP调用后端接口示例(OkHttp)
OkHttpClient client = new OkHttpClient(); MediaType jsonMediaType = MediaType.parse("application/json"); RequestBody requestBody = RequestBody.create(jsonMediaType, "{" + "\"targetToken\": \"用户端设备令牌\"," + "\"title\": \"系统通知\"," + "\"content\": \"管理员发布了新公告\"" + "}"); Request request = new Request.Builder() .url("你的后端接口地址") .post(requestBody) .addHeader("Content-Type", "application/json") .build(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { // 发送成功逻辑 } else { // 发送失败逻辑,可打印response.body().string()排查问题 } } catch (IOException e) { e.printStackTrace(); }
三、临时测试方案(不推荐生产)
若仅用于测试,可直接在管理员端APP调用FCM API,但测试后需立即更换服务器密钥:
OkHttpClient client = new OkHttpClient(); MediaType jsonMediaType = MediaType.parse("application/json"); RequestBody requestBody = RequestBody.create(jsonMediaType, "{" + "\"to\": \"用户端设备令牌\"," + "\"notification\": {" + "\"title\": \"测试通知\"," + "\"body\": \"管理员端发送的测试消息\"" + "}" + "}"); Request request = new Request.Builder() .url("https://fcm.googleapis.com/fcm/send") .post(requestBody) .addHeader("Authorization", "key=你的FCM服务器密钥") .addHeader("Content-Type", "application/json") .build(); try { Response response = client.newCall(request).execute(); Log.d("FCM_TEST", response.body().string()); } catch (IOException e) { e.printStackTrace(); }
四、常见问题排查
- 设备令牌有效性:用户端卸载重装后令牌会变更,需重新上传。
- 服务器密钥正确性:密钥错误会返回
401 Unauthorized响应。 - 网络权限:管理员端APP需在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET" />。 - 通知权限:用户端需开启通知权限,否则无法接收推送。
- FCM初始化:确保两个APP的
Application类中执行FirebaseApp.initializeApp(this),或依赖自动初始化逻辑。
内容的提问来源于stack exchange,提问作者Raouf_Kelani
相关产品推荐
相关产品推荐

