-
Notifications
You must be signed in to change notification settings - Fork 5
Description
有三个topic要谈:
- sending push notification to a topic
- directly to the users’ device
- sending messages with additional data payload.
消息格式: https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages
pom.xml
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>6.13.0</version>
</dependency>最新版本请参见: https://firebase.google.com/docs/admin/setup#add-sdk
Authenticate a service account and authorize it to access Firebase services
you must generate a private key file in JSON format.
To generate a private key file for your service account:
In the Firebase console, open Settings > Service Accounts.
Click Generate New Private Key, then confirm by clicking Generate Key.
Securely store the JSON file containing the key.
使用以上json文件初始化FCM Admin SDK
FileInputStream serviceAccount =
new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com")
.build();
FirebaseApp.initializeApp(options);如果是通过设置环境变量 GOOGLE_APPLICATION_CREDENTIALS
指定json文件的位置, 则以上代码修改为:
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);例子: export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"
或者使用以上json文件得到一个short-lived JWT token
private static String getAccessToken() throws IOException {
GoogleCredential googleCredential = GoogleCredential
.fromStream(new FileInputStream("service-account.json"))
.createScoped(Arrays.asList(SCOPES));
googleCredential.refreshToken();
return googleCredential.getAccessToken();
}如果要使用FCM service, SCOPES的值必须为 https://www.googleapis.com/auth/firebase.messaging
使用JWT Token
headers: {
'Authorization': 'Bearer ' + accessToken
}以上整理自: https://firebase.google.com/docs/cloud-messaging/auth-server
搭建FCM Server的要求
https://firebase.google.com/docs/cloud-messaging/server#role
搭建FCM Server的两种方式
- FCM HTTP v1 API
- Firebase Admin SDK for FCM (封装了FCM HTTP v1 API)
发送消息 (cyper实战)
public interface FcmService {
/**
* 发送消息到指定设备.
*
* @param deviceToken 设备Token
* @param title 标题
* @param body 内容
* @param payload 其他额外参数
* @throws FirebaseMessagingException
*/
void sendTokenMessage(String deviceToken, String title, String body, Map<String, String> payload)
throws FirebaseMessagingException;
/**
* 发送topic.
*
* @param topic 主题
* @param title 标题
* @param body 内容
* @param payload 其他额外参数
* @throws FirebaseMessagingException
*/
void sendTopicMessage(String topic, String title, String body, Map<String, String> payload)
throws FirebaseMessagingException;
/**
* 群发消息到多个设备
*
* @param deviceTokens 多个设备的Token
* @param title 标题
* @param body 内容
* @param payload 其他额外参数
* @throws FirebaseMessagingException
*/
void sendMessage2MultiDevices(List<String> deviceTokens, String title, String body, Map<String, String> payload)
throws FirebaseMessagingException;
}
@Service
@Slf4j
public class FcmServiceImpl implements FcmService {
@Override
public void sendTokenMessage(String deviceToken, String title, String body, Map<String, String> payload)
throws FirebaseMessagingException {
sendMessage(deviceToken, title, body, payload, false);
}
@Override
public void sendTopicMessage(String topic, String title, String body, Map<String, String> payload)
throws FirebaseMessagingException {
sendMessage(topic, title, body, payload, true);
}
private void sendMessage(String topicOrToken, String title, String body, Map<String, String> payload,
boolean isTopic) throws FirebaseMessagingException {
// See documentation on defining a message payload.
Builder builder = Notification.builder();
builder.setTitle(title);
builder.setBody(body);
Notification notification = builder.build();
Message.Builder messageBuilder = Message.builder().setNotification(notification);
if (payload != null) {
messageBuilder.putAllData(payload);
}
if (isTopic) {
messageBuilder.setTopic(topicOrToken);
} else {
messageBuilder.setToken(topicOrToken);
}
// Send a message to the device corresponding to the provided registration
// token.
String response = FirebaseMessaging.getInstance().send(messageBuilder.build());
if (log.isInfoEnabled()) {
log.info(response);
}
}
@Override
public void sendMessage2MultiDevices(List<String> deviceTokens, String title, String body,
Map<String, String> payload) throws FirebaseMessagingException {
Builder builder = Notification.builder();
builder.setTitle(title);
builder.setBody(body);
Notification notification = builder.build();
// @formatter:off
MulticastMessage.Builder messageBuilder = MulticastMessage.builder()
.setNotification(notification)
.addAllTokens(deviceTokens);
if(payload != null) {
messageBuilder.putAllData(payload);
}
// @formatter:on
BatchResponse response = FirebaseMessaging.getInstance().sendMulticast(messageBuilder.build());
if (log.isInfoEnabled()) {
log.info(response.getSuccessCount() + " messages were sent successfully");
}
}
}App端 用到的 Dart package (pub spec)
Pub Spec: firebase_messaging 6.0.13
References
Spring Boot: Send push notifications from Spring Boot server-side application using FCM
新鲜出炉的:Flutter Push Notifications using flutter firebase messaging with example
Concise: FCM Push Notifications for Flutter
FilledStacks: Push Notifications in Flutter using Firebase