코딩마을방범대

[FCM] 푸시 메시지를 보내는 방법 2가지 본문

💡 백엔드/FCM ( Firebase )

[FCM] 푸시 메시지를 보내는 방법 2가지

신짱구 5세 2023. 7. 6. 16:34
728x90

 

 

 

 

메시지를 보내는 방법에도 2가지가 있다!

 

첫 번째,

FCM 공식 링크를 통해 보내는 방법이며, 이 방법은 컨트롤러를 따로 구성할 필요없이 정해진 변수명에 알맞은 값들을 넣어서 호출하기만 하면 되므로, 테스트용에 적합하다.

 

두 번째,

직접 컨트롤러를 구성하는 방식인데, 이 방법은 본인만의 API 주소를 구성하여 작업할 수 있어서 테스트용이 아닌 정식 서버에서 사용하기 적합하다.

 

 

FCM 메시지 매개변수

 

 

 


 

 

 

 

 

 

1. FCM 공식 링크를 이용해 메시지 보내기

 

아래 사진을 보면 Cloud Messaging API(기존) 사용 중지됨 이 표시되어 있다.

따라서 현재는 V1을 이용하고 있는 것이며, 이용 방법에 따라 메시지 전송 방법이 다르다.

 

현재는 V1 방식만을 지원하므로 명심하자! ( 둘 다 Post 메소드! )

API 방식 주소
FCM v1 HTTP API https://fcm.googleapis.com/v1/projects/프로젝트 아이디/messages:send
FCM 기존 HTTP API https://fcm.googleapis.com/fcm/send

 

FCM 기존 HTTP API의 Body는 아래와 같으니 참고만!

Headers 설정!
Authorization: key=서버키
Content-Type: application/json

Body 설정!
{    
      "notification": {        
            "time": "FCM Message",
            "title": "TEST 제목",
            "body": "알림테스트"    
      },"data" : {       
            "userKey" : "dbkim",        
            "email" : "dbkim@dbkim.com"    
      },    
      "to": "FCM 토큰값"
}

 

 


 

1. Header 설정

변수명
Authorization Bearer OAuth2 토큰값(FCM 토큰아님!!)
Content-Type application/json

 

 

 

Authorization에 들어가는 OAuth2 값은 자바를 통해 얻는 방법 또는 사이트에서 얻는 방법이 있다.

 

 

1. Java

참고사이트

public class AuthToken {
    private static final String MESSAGING_SCOPE = "https://www.googleapis.com/auth/firebase.messaging";
    private static final String[] SCOPES = { MESSAGING_SCOPE };

    public static String getAccessToken() throws IOException {
        URL url = ResourceUtils.getURL("classpath:서버키 json파일 경로");

        GoogleCredentials googleCredentials = GoogleCredentials
                .fromStream(url.openStream())
                .createScoped(Arrays.asList(SCOPES));
        googleCredentials.refresh();
        return googleCredentials.getAccessToken().getTokenValue();
    }
}

 

 


 

 

2. 사이트

https://developers.google.com/oauthplayground/

 

OAuth 2.0 Playground

Request Body Manual entry Enter the data that will be added to the body of the request: File You may choose to send a file as part of the request. When both a file and manual content are provided both will be sent using a multipart request. You may send fi

developers.google.com

 

 

1. 'https://www.googleapis.com/auth/cloud-platform' 선택 후 'Authorize APIs' 클릭

 

 

2. 구글 계정 액세스 허용

 

 

3. 'Exchange authorization code for tokens' 클릭 후 Access token 복사

※ 이 사이트 내에서도 메시지 전송 테스트를 할 수 있다.

 

 

 

 

 


 

 

2. Body 설정

validate_only 는 test 용도일 경우 true를 주고 아닐 경우 추가하지 않아도 됨!

{    
      "validate_only": true,
      "message": {
            "token": "FCM 토큰값",
            "notification": {
                  "body": "메시지 내용",          
                  "title": "메시지 제목"        
            },"data" : {
                  "userKey" : "dbkim",        
                  "email" : "dbkim@dbkim.com"    
            }
      }
}

 

정상적으로 호출되었을 경우 아래와 같이 Message ID가 리턴된다!

 

 

 

 

 

 


 

 

 

 

 

 

2. 컨트롤러를 구성하여 메시지 보내기

※ Java 부분은 앱과 동일함

 

gradle

implementation 'com.google.firebase:firebase-admin:8.1.0'

 


 

yml

fcm:
  database-name: [project_id]
  privatekey-path: classpath:[json파일 경로]

 


 

FCMSettings

@Getter
@Component
@ConfigurationProperties(prefix = "fcm")
public class FCMSettings {
	// 자신의 프로젝트에 생성된 Realtime Database 이름
	private String databaseName;
	// 위에서 생성한 비공개키 json 파일
	private String privateKeyPath;
}

 


 

FcmConf

※ DatabaseUrl 은 Firebase 홈페이지의 Realtime Database 생성 후 링크 참고 (필수 아님!)

@Configuration
@RequiredArgsConstructor
public class FCMConfig {
	private final FCMSettings fcmSettings;
    
	@PostConstruct
	public void initialize() throws IOException {
		URL url = ResourceUtils.getURL(fcmSettings.getPrivateKeyPath());
        
		//FireBase SDK 초기화
		FirebaseOptions options = FirebaseOptions.builder()
			.setCredentials(GoogleCredentials.fromStream(url.openStream()))
			.setDatabaseUrl("https://" + fcmSettings.getDatabaseName() + ".firebaseio.com")
			.build();
            
		// FirebaseApp.initializeApp(options, 설정해줄 이름);
		// 위와 같이 설정 시 fcm 서버에 대한 분기처리가 가능하다.
		FirebaseApp firebaseApp = FirebaseApp.initializeApp(options);
	}
}

 


 

 

FCMService

@Service
@RequiredArgsConstructor
public class FCMNotificationService {
    private final FirebaseMessaging firebaseMessaging;

    public boolean sendNotificationByToken(FCMNotificationRequestDto request){
        Notification notification = Notification.builder()
                .setTitle(request.getTitle())
                .setBody(request.getBody())
                .build();
        Message message = Message.builder()
                .setToken(request.getToken())
                .setNotification(notification)
                // 데이터를 담을 경우 앱에서 메시지의 데이터를 가져올 수 있음
                .putAllData(new HashMap<String, String>(){{
                	put("test", "test value"
                }})
                // 아래처럼 하나하나 담아줄 수도 있음
                //.putData("test", "test Value")
                .build();

        try{
			// FirebaseMessaging.getInstance(FirebaseApp.getInstance(설정해준 이름)).send(message);
			// conf에서 분기 처리 했을 경우 전송 때 이름값을 전달해주면 된다.
            FirebaseMessaging.getInstance().send(message);
            return true;
        } catch (FirebaseMessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

 

Message에 수신자를 설정하는 옵션들

setToken(String) 특정 기기에 전송
addAllToken(List<String>) 여러 기기에 전송 (MulticastMessage를 사용, 내부적으로 sendAll() 를 호출)
setTopic(String) 주제로 전송
setCondition(String) 조건을 이용해 전송
ex) stock-GOOG' in topics || 'industry-tech' in topics

 

Message를 전송하는 옵션

sendAll(List<Message>) 일괄 메시지 전송
sendMulticast(MulticastMessage) addAllToken 을 통해 토큰 리스트 받아서 전송
send(Message) 하나의 메시지 전송

 

 

 

 

 

728x90