[안드로이드] FCM 웹(JAVA)서버에서 푸시메세지 보내기
안드로이드의 기존 GCM에서 FCM으로 바뀌었다
구글 클라우드 메세지에서 파이어베이스 클라우드 메세지로 바뀐건진 정확히 모르겠지만..
일단 뜬금없이 웹개발하다가 갑자기 회사에서 안드로이드 개발할 일이 생겼지만
웹뷰로 때워버리자! 라고 외친 후 만들어 놓고 보니 안드로이드 알림 메세지가 가야 한단다...
하....
그래서 뭐 삽질좀 하고 여기저기 뒤적뒤적이면서 구현을 했다
일단 가장 먼저
https://console.firebase.google.com/u/0/
당연히 구글 아이디는 있을것이지 콘솔 파이어베이스로 들어가
알람메세지 구현알 어플을 등록해준다.
이곳의 도움을 많이 받았다. 기초 설정은 여기 보고 따라하자
사실 저 블로그만 봐도
어지간하면 구현 가능하다.
진짜 생각보다 좀 간단하다.
1. Android JAVA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import android.content.SharedPreferences; import android.util.Log; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceIdService; import java.io.IOException; import okhttp3.FormBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService { private static final String TAG = "MyFirebaseIIDService"; /** * Called if InstanceID token is updated. This may occur if the security of * the previous token had been compromised. Note that this is called when the InstanceID token * is initially generated so this is where you would retrieve the token. */ // [START refresh_token] @Override public void onTokenRefresh() { // 설치할때 여기서 토큰을 자동으로 만들어 준다 String refreshedToken = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken); // 생성한 토큰을 서버로 날려서 저장하기 위해서 만든거 sendRegistrationToServer(refreshedToken); } private void sendRegistrationToServer(String token) { // Add custom implementation, as needed. // OKHTTP를 이용해 웹서버로 토큰값을 날려준다. OkHttpClient client = new OkHttpClient(); RequestBody body = new FormBody.Builder() .add("Token", token) .build(); //request Request request = new Request.Builder() .url("토큰 저장할라고 보낼 URL") .post(body) .build(); try { client.newCall(request).execute(); } catch (IOException e) { e.printStackTrace(); } } } | cs |
여기서 우리가 잘 봐야 할 건
30번 라인과
37번라인의 sendRegistrationToServer 메소드다
30번라인에서 토큰을 생성하는데 여기선 어플을 설치할때 한번 생성한다.
그럼 만들어지자마자
37번라인 메소드로 날려서 HTTP로 전송한다.
그럼 웹서버에서 저 토큰을 받고 저장을 하게 되고
그 해당 토큰으로 메세지를 날려주면 되는 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.media.RingtoneManager; import android.net.Uri; import android.support.v4.app.NotificationCompat; import com.google.firebase.messaging.RemoteMessage; public class MyFirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService { private static final String TAG = "FirebaseMsgService"; // [START receive_message] @Override public void onMessageReceived(RemoteMessage remoteMessage) { //추가한것 sendNotification(remoteMessage.getData().get("message")); } private void sendNotification(String messageBody) { Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT); Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("FCM Push Test") // 이부분은 어플 켜놓은 상태에서 알림 메세지 받으면 저 텍스트로 띄워준다. .setContentText(messageBody) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); } } | cs |
MyFirebaseMessagingService.java 얘는 알림메세지를 받았을때 처리하는건데
사실 딱히 건들일거 없이 그대로 사용 하면 된다.
일단 저 블로그에서
MyFirebaseInstanceIDService.java 와
MyFirebaseMessagingService.java
이 두개를 구현했다면
여기로 들어와서 앱단위로 앱선택하고 보내면
모든 앱 설치자들에게 메세지가 날아간다.
하지만 우린 웹서버에서 푸시메세지를 날려주고 싶을 것이다.
알람이라면 뭐 값이 변한다거나 새로운 정보가 등록 되었을때 날려줘야 하니까
그때마다 저기 접속해서 날려주기엔 너무 귀찮으니까 분명히
웹서버에서 인터벌을 돌리든 트리거를 걸든 해서 웹서버에서 날려주고 싶을 것이다
그런데 웹서버에서 날려주는건
잘 안나와있고 복사 붙여넣기 해도 안되는 경우도 있고 하니까
내가 해서 성공한 코드를 보자
★
2. JAVA Web Server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | @RequestMapping(value="mobile/sendFCM") public String index(Model model, HttpServletRequest request, HttpSession session, MobileTokenVO vo)throws Exception{ List<MobileTokenVO> tokenList = fcmService.loadFCMInfoList(vo); String token = tokenList.get(count).getDEVICE_ID(); final String apiKey = "파이어 베이스의 서버 API키를 여기에 넣는다"; URL url = new URL("https://fcm.googleapis.com/fcm/send"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("Authorization", "key=" + apiKey); conn.setDoOutput(true); String userId =(String) request.getSession().getAttribute("ssUserId"); // 이렇게 보내면 주제를 ALL로 지정해놓은 모든 사람들한테 알림을 날려준다. String input = "{\"notification\" : {\"title\" : \"여기다 제목 넣기 \", \"body\" : \"여기다 내용 넣기\"}, \"to\":\"/topics/ALL\"}"; // 이걸로 보내면 특정 토큰을 가지고있는 어플에만 알림을 날려준다 위에 둘중에 한개 골라서 날려주자 String input = "{\"notification\" : {\"title\" : \" 여기다 제목넣기 \", \"body\" : \"여기다 내용 넣기\"}, \"to\":\" 여기가 받을 사람 토큰 \"}"; OutputStream os = conn.getOutputStream(); // 서버에서 날려서 한글 깨지는 사람은 아래처럼 UTF-8로 인코딩해서 날려주자 os.write(input.getBytes("UTF-8")); os.flush(); os.close(); int responseCode = conn.getResponseCode(); System.out.println("\nSending 'POST' request to URL : " + url); System.out.println("Post parameters : " + input); System.out.println("Response Code : " + responseCode); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); // print result System.out.println(response.toString()); return "jsonView"; } | cs |
위의 코드처럼 쓰면 된다.
8번 라인의 API키는
저 파이어베이스 콘솔에서 빨간동그라미 누르고 프로젝트 설정의 클라우드 메세징으로 가면
서버키가 나와있다 그 서버키를 넣으면 된다.
그런데 20번 21번 라인의 주제가 ALL인걸 어떻게 지정 하냐고?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 웹뷰 셋팅팅 mWebView = (WebView)findViewById(webView); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.loadUrl(myUrl+"/mobile/login"); mWebView.setWebChromeClient(new WebChromeClient()); mWebView.setWebViewClient(new WebViewClientClass()); mWebView.addJavascriptInterface(new AndroidBridge(), "android"); //이렇게 ALL 추가 하면 이 디바이스는 ALL을 구독한다는 얘기가 된다. FirebaseMessaging.getInstance().subscribeToTopic("ALL"); } | cs |
안드로이드의 MainActivity.java 의 oncreate에다가 저 18번 라인을 추가 해주자
그런데 주제 등록은 즉시 안되고 몇시간 기다리거나 몇일 기다려야 등록 되는 경우도
있다고 하니까 급하게 하진 말자.
그리고 24번 라인에 들어가는 토큰은 MyFirebaseInstanceIDService.java 의 36번 메소드에 날려준 값이다
여기까지가 기초적인 FCM을 이용한 메세지 보내는 방법이다!
다음강좌는
저 토큰아이디를 어떻게 사용자 ID랑 묶어서 저장하고 원하는 사용자에게
보낼 수 있는지 알아보자
2017/07/10 - [Yame Programmer/Android] - [안드로이드] FCM 토큰 저장방법 개별 보내는 방법 SharedPreferences 사용