본문 바로가기
Framework & Lib & API/API

[FCM]Firebase(파이어베이스)와 스프링 연동(토큰방식 여러개 한번에 푸시알림 보내기)

by 코딩공장공장장 2020. 12. 21.

구글링을 하면 파이어베이스 콘솔에서 프로젝트 만드는 방법 부터 주제구독 방식으로 푸시알림을 보내는 법,

 

토큰 방식으로 푸시알림을 보내는 법 자세하게 나와 있는 포스팅들이 많은데요,

 

푸시알림 토큰 방식을 처음 이용하시는 분들은 다른 포스팅이나 커뮤니티를 보고 구현해보고 오시기를 추천합니다. 

 

기존의 토큰 방법에서 몇가지 변경되는 부분만 있으므로 변경되는 부분에 대해서만 다뤄보겠습니다.

 

참고로 따라할수 있게 하나부터 열까지의 내용을 다 적은게 아니라 제가 어떻게 구현했는지 개괄적으로 

 

설명한 글입니다.

 

 

 

 

 

 

 

 

 

스프링 웹서버

 

 

의존설정

<dependency>
 		 <groupId>com.google.firebase</groupId>
 		 <artifactId>firebase-admin</artifactId>
 		 <version>7.0.1</version>
	</dependency>

의존 모듈 7.0.1로 설명을 하도록 하겠습니다. 

 

너무 오래된 버전은 클래스 파일을 import하지 못할수 있습니다.

 

 

 

컨트롤러

@RequestMapping(value="apply", method = RequestMethod.POST)
	public String apply2(ApplyForm apply, Model model, HttpSession session) {
			TeacherApplyService teacherApplyService = ctx.getBean("teacherApplyService", TeacherApplyService.class );
			String locale= apply.getLocale1()+" "+apply.getLocale2();
			teacherApplyService.sendPushNotificationTarget(locale,apply.getCate());
			ctx.close();
			return "redirect:applysuccess";
	
		
	}

웹서버에서 apply가 매핑되어있는 페이지에서 post 요청이 들어오면  푸시알림이 실행되도록 설정되어있는 것입니다. 

 

sendPushNotificationTarget(locale, apply.getCate()); 메서드를 통해 특정 지역에서 특정 카테고리를 참고하고 있는 

 

사람들에게 푸시알림을 보내기 위해 제가 구현한 메서드입니다.

 

 

 

서비스 클래스

public void sendPushNotificationTarget(String locale, String cate) {
		HashMap<String, String> map = new HashMap<>();
		map.put("locale",locale);
		map.put("cate",cate);
		List<String> emailList = applyDao.takeEmailForPushTarget(map);
		List<String> registrationTokens = applyDao.takeTokenForPushTarget(emailList);
		if(registrationTokens.size()!=0) {
			FcmUtil fcm = new FcmUtil();
			String title= "\""+cate+"\""+"수업에 지원하세요";
			String content = "\""+locale+"\""+"에  "+"\""+cate+"\""+"수업 요청 학생이 있습니다";
			try {
				fcm.send_Multi_FCMtoken(registrationTokens, title, content);
			}catch(Exception e) {}
		}
	}

 

서비스클래스에서 위에처럼 구현해 놨구요.

 

DB에서 해당 locale과 cate의 조건에 맞는 email과 이를 통해 기기의 토큰 값을 가져온 것입니다. 

 

fcm.send_multi_Fcmtoken(regeistrationTokens, title, content); 메서드를 통해 푸시알림을 보내는 것인데

 

 FCMUtil 클래스는 제가 구현한것입니다. 

 

FCMUtil 클래스 

public class FcmUtil {
	
	public void send_Multi_FCMtoken(List<String> registrationTokens, String title, String content) throws IOException, FirebaseMessagingException {
		FileInputStream serviceAccount = new FileInputStream("인증파일경로");
		
		FirebaseOptions options = FirebaseOptions.builder()
		  .setCredentials(GoogleCredentials.fromStream(serviceAccount))
		  .setDatabaseUrl("본인 파이어베이스 url")
		  .build();
		
		if(FirebaseApp.getApps().isEmpty()) {
			FirebaseApp.initializeApp(options);
		}
		
		
		MulticastMessage message = MulticastMessage.builder()
			    .putData("title", title)
			    .putData("content",content)
			    .addAllTokens(registrationTokens)
			    .build();
			
				BatchResponse response = FirebaseMessaging.getInstance().sendMulticast(message);	
				
				if (response.getFailureCount() > 0) {
					  List<SendResponse> responses = response.getResponses();
					  List<String> failedTokens = new ArrayList<>();
					  for (int i = 0; i < responses.size(); i++) {
					    if (!responses.get(i).isSuccessful()) {
					      // The order of responses corresponds to the order of the registration tokens.
					      failedTokens.add(registrationTokens.get(i));
					    }
					  }

					 
				}
	}

}

 

사실 이미 웹서버가 있고 푸시알림을 사용하고 있는 분들이라면 지금 이 위의 코드만 봐도 무방하다고 생각합니다. 

 

위의 부분만 다르고 나머지는 다 똑같습니다. 

 

오래된 메이븐 버전을 사용하는 분들을 클래스 메소드 이름이 조금 다를수 있을 것입니다. 

 

저 또한 오래된 버전을 사용하고 있었어서 deprecated 되어 있는 부분들이 많아 여기저기 찾아보면서 수정을 했네요. 

 

 

안드로이드 MyFireBaseMessagingService 클래스

public class MyFireBaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onNewToken(String token){

        Log.d("FCM Log", "Refreshed token: "+token);
    }
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage){
        if(remoteMessage.getData().size() > 0){

            Log.d("FCM Log","message: "+remoteMessage.getData());
            String messageBody = remoteMessage.getData().get("content");
            String messageTitle = remoteMessage.getData().get("title");

            Intent intent = new Intent(this, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this,0, intent , PendingIntent.FLAG_ONE_SHOT);
            String channelId = "Channel ID";
            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

            NotificationCompat.Builder notificationBuilder =
                    new NotificationCompat.Builder(this, channelId)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle(messageTitle)
                    .setContentText(messageBody)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setVibrate(new long[]{1000, 1000})
                    .setLights(Color.BLUE,500,2000)
                    .setContentIntent(pendingIntent)
                    ;

            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
                String channelName = "Channel Name";
                NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
                notificationManager.createNotificationChannel(channel);
            }
            notificationManager.notify(0, notificationBuilder.build());
        }
    }
}

 

 

 

자 이렇게 구현하는 방법에 대해 알아봤습니다. 

 

포스팅이 하나하나 친절하게 실습해볼수 있는 글은 아닙니다. 

 

이미 기존에 푸시알림을 사용하는 어플리케이션이 있는 경우에 추가/변경하는데 참고하기 좋은 글입니다.

반응형