// https://mvnrepository.com/artifact/com.google.firebase/firebase-admin
implementation 'com.google.firebase:firebase-admin:8.1.0'
// https://mvnrepository.com/artifact/org.modelmapper/modelmapper
implementation 'org.modelmapper:modelmapper:2.4.4'
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.io.FileInputStream;
@Configuration
public class FirebaseConfig {
private final String path = "src/main/resources/firebase/firebaseAccountKey.json";
@PostConstruct
public void init(){
try{
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(new FileInputStream(path))).build();
if (FirebaseApp.getApps().isEmpty()) {
FirebaseApp.initializeApp(options);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public String getAccessToken() throws IOException {
FileInputStream inputStream = new FileInputStream("src/main/resources/firebase/firebaseAccountKey.json");
GoogleCredentials googleCredentials = GoogleCredentials
.fromStream(inputStream)
.createScoped(List.of("https://www.googleapis.com/auth/cloud-platform"));
googleCredentials.refreshIfExpired();
return googleCredentials.getAccessToken().getTokenValue();
}
private String makeMessage(String token, String title, String body) throws JsonProcessingException {
FcmMessage fcmMessage = FcmMessage.builder()
.message(FcmMessage.Message.builder()
.token(token)
.notification(FcmMessage.Notification.builder()
.title(title)
.body(body)
.image(null)
.build())
.build())
.validate_only(false)
.build();
return objectMapper.writeValueAsString(fcmMessage);
}
FcmMessage
@AllArgsConstructor
@Builder
@Data
public class FcmMessage {
private boolean validate_only;
private Message message;
@AllArgsConstructor
@Builder
@Data
public static class Message {
private Notification notification;
private String token;
}
@AllArgsConstructor
@Builder
@Data
public static class Notification {
private String title;
private String body;
private String image;
}
}
public void sendMessageTo(String token, String title, String body) throws IOException {
String message = makeMessage(token, title, body);
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(MediaType.get("application/json; charset=utf-8"), message);
Request request = new Request.Builder()
.url(API_URL)
.post(requestBody)
.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken())
.addHeader(HttpHeaders.CONTENT_TYPE, "application/json; UTF-8")
.build();
Response response = client.newCall(request)
.execute();
log.info(response.body().toString());
}
특정유저에게 전송해야 할 경우가 많으니 귀찮으니까 빈으로 등록하자
@Slf4j
@RequiredArgsConstructor
@Service
public class FcmSendService {
private final FirebaseCloudMessageService fcmService;
private final UserTokenService userTokenService;
private final UserNotificationService userNotificationService;
public void sendFCM(User user,String title,String body) throws Exception {
byte[] decode = Base64.getDecoder().decode(userTokenService.findTokenByUserIdAndType(user.getId(), "fcm"));
String token = new String(decode, StandardCharsets.UTF_8);
fcmService.sendMessageTo(token,title,body);
userNotificationService.save(new UserNotification(title, body, user));
}
}