앞서 적용한 push notification을 firebase console에서 테스트 해보면 앱이 비활성화 되어 있는 상태에서는 FirebaseMessagingService 의 onMessageReceived를 타지 않습니다.
10:22 분은 앱이 비활성화 된 상태에서 보낸 알림이고
10:23 분은 앱이 활성화 된 상태에서 보낸 알림입니다.
onMessageReceived에 해놓은 설정이 적용되지 않는 것을 확인 할 수 있습니다.
해결 방법
앱이 백그라운드에서 실행중이거나 죽어있을때 적용 하려면 fcm api를 직접 호출 해 주면 됩니다.
api url :: https://fcm.googleapis.com/fcm/send
node.js 를 통해 api를 호출하는걸 예로 들겠습니다.
function sendTopicMessage(title, content, imgUrl, link) {
var message = { title : title , content : content, imgUrl : imgUrl , link : link }
request({
url : 'https://fcm.googleapis.com/fcm/send',
method : 'POST',
headers : {
'Content-Type' : ' application/json',
'Authorization' : 'key=Firebase API KEY'
},
body : JSON.stringify({
"data" : {
"message" : message
},
"to" : "/topics/notice"
})
}, function(error, response, body) {
if (error) {
console.error(error, response, body);
} else if (response.statusCode >= 400) {
console.error('HTTP Error: ' + response.statusCode + ' - '
+ response.statusMessage + '\n' + body);
} else {
console.log('Done')
}
});
}
url은 'https://fcm.googleapis.com/fcm/send' method = POST 방식 , json 타입으로 설정하였습니다.
header에는 Authorization을 꼭 넣어 주셔야 합니다. Firebase API KEY에는 발급 받으신 api key를 넣어줍니다.
body의 to는 보낼 대상으로 /topic/토픽명 으로 하게 되면 해당 토픽 전체 사용자에게 메세지를 발송 합니다.
ex) FirebaseMessaging.getInstance().subscribeToTopic("notice");
/topic 대신에 사용자별 토큰 값을 넣게 되면 특정 사용자에게만 보낼 수 있습니다.
ex)
String token = FirebaseInstanceId.getInstance().getToken();
android 프로젝트에서 저렇게 하면 사용자 token값을 얻어 올 수 있고 그 값이
fmPgYSi3Iww:APA91bHKi23li9Kn1YKPiSTX4cfdwJ4BBjTHHRvhZBYnz4Rw2aKWgLYNgTKGJX2-tmjoZRib0XonkxL34yQk-O_pplT-mR46dd3l04NL1BCW3D47dd2Ra87ejktW1ju6FUw_AUZrndb9wt
위와같이 나오는데 저 값을 to 에 넣으면 해당 사용자 에게 푸시알림 발송이 가능합니다.
"to" : "fmPgYSi3Iww:APA91bHKi23li9Kn1YKPiSTX4cfdwJ4BBjTHHRvhZBYnz4Rw2aKWgLYNgTKGJX2-tmjoZRib0XonkxL34yQk-O_pplT-mR46dd3l04NL1BCW3D47dd2Ra87ejktW1ju6FUw_AUZrndb9wt"
------------------------------
fcm messaging api를 사용해서 보내게 되면 앱이 background에서 실행 중이거나 kill 되어 있을때에도 onMessageReceived를 타는것을 확일 할 수 있습니다.
* 위 코드의 var message는 제 프로젝트에 맞춰 놓은거라 각자 프로젝트에 맞게 쓰시면 됩니다.
+ 내용 추가 2017-01-13
postman으로 테스트 할 경우 파라미터 세팅
1. 상단 POST , fcm URL 입력
2. headers 탭에 content-Type 과 authorizatino 추가 (api key값은 지웠습니다)
3. body에 JSON 형식으로 위와같이 적고 raw 선택 오른쪽에서 타입은 JSON을 선택 합니다
4. Send를 누르면 테스트 가능합니다.
OkHTTP Generator 결과
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"data\" : {\"message\" : {\"title\":\"test\",\"content\":\"testcontent\",\"imgUrl\":\"\",\"link\":\"\"}},\"to\" : \"/topics/noticeMsg\"}");
Request request = new Request.Builder()
.url("https://fcm.googleapis.com/fcm/send")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("authorization", "key=api키")
.addHeader("cache-control", "no-cache")
.addHeader("postman-token", "postman토큰")
.build();
Response response = client.newCall(request).execute();
+ 내용 추가
java에서 firebase messaging api 호출 하는 방법 추가 했습니다
LINK :: http://trandent.com/board/Android/detail/764
해결햇습니다 ㅜㅜ 그냥 var obj = new Object(); obj.title = 'testtitle'; obj.content = 'testcontent'; obj.imgUrl = 'testimgUrl'; obj.link = 'testlink'; var message = JSON.stringify(obj); 부분에 obj.to = "/topics/notice"; 하니까 되네요 ;; 따로 써줘야는건줄알고 .. 하하.. 만들다 또 막히면 질문드릴게요 감사합니다!
답변 감사드려요 말씀 주신데로 자바스크립트 아작스로 해보았는데 var obj = new Object(); obj.title = 'testtitle'; obj.content = 'testcontent'; obj.imgUrl = 'testimgUrl'; obj.link = 'testlink'; var message = JSON.stringify(obj); $.ajax({ type: 'POST', url: 'https://fcm.googleapis.com/fcm/send', beforeSend : function(xhr){ xhr.setRequestHeader("Authorization", "key="); xhr.setRequestHeader("Content-type","application/json"); }, data : message, success : function(data) { },error : function(data,xhr){ } }) 이때 400 에러가 뜨더라구요 포스트맨은 Error=MissingRegistration 이렇게 에러가 뜨고 아마도 "to" : "/topics/notice" 이부분이 빠진거같은데 위소스에 어디부분에 그걸 넣어야 할까요 ㅜ
ajax로 fcm에 다이렉트로 쏘게 되면 { title : "타이틀내용" , content : "본문내용", imgUrl : "http://~~~" , link : "http://@@@@@" } 이런식으로 데이터를 넣어서 보냈다면 firebaseMessagingService에서 받아서 jsonobject로 변환 후 꺼내서 쓰셔야 될 것 같습니다.
안녕하세요 자바스크립트로 하시려면 request({ url : 'https://fcm.googleapis.com/fcm/send', method : 'POST', headers : { 'Content-Type' : ' application/json', 'Authorization' : 'key=Firebase API KEY' }, body : JSON.stringify({ "data" : { "message" : message }, "to" : "/topics/notice" }) }, function(error, response, body) { }); 위 코드를 ajax 형태로 바꾸면 동작할것으로 생각됩니다. $.ajax({ type: 'POST', url: '', data: , dataType : 'json', success : function(data) { },error : function(data){} })
아 그리고 또 문제가있는게 노드로 해서 안되서 포스트맨으로 위에올려주신거대로 햇는데 메세지 부분에 { title : title , content : content, imgUrl : imgUrl , link : link } 이게 그대로 찍혀나오더라구요 푸쉬 부분에 ㅜㅜ 타이틀은 Push Title 이걸로오고 FirebaseMessagingService 이부분에 수정해야할게있나요?
안녕하세요 잘 배우고있습니다 근데 문제가 좀 생겨서 질문좀 드릴게요 ㅜ 글중에 node.js 로 함수선언하신다음에 보내는부분이있는데요 노드는 제가 정확하게 잘알지를못해서 문제가 좀 생겻습니다 노드는 일단 작동되도록 설치는 다되어있구요 파일을 notice.js 로 생성해서 위에 소스를 그대로 넣고 실행시켜봣는데요 request({ ^ ReferenceError: request is not defined at sendTopicMessage (/web_root/nodejs/notice.js:5:9) at Object.(/web_root/nodejs/notice.js:33:1) at Module._compile (module.js:660:30) at Object.Module._extensions..js (module.js:671:10) at Module.load (module.js:573:32) at tryModuleLoad (module.js:513:12) at Function.Module._load (module.js:505:3) at Function.Module.runMain (module.js:701:10) at startup (bootstrap_node.js:193:16) at bootstrap_node.js:617:3 이러한 에러가 뜨더라구요 node는 처음인데 혹시 request 가 모듈같은거일까요? 모듈을 설치해야하는 문제인걸까요 혹시 .. ㅎㅎ 아니면 혹시 자바스크립트버전으론 api 할수없을까요 ..
OkHTTP Generator 결과 이건 어디서 처리하는거죠? 초보라서 따라가기도 어렵네요 ㅎㅎ 포스트맨으로 테스트 한번 해볼려는데 실행 시 아래에 { "message_id": 1234567890 } 이런것만 출력되고 어플에 메세지는 오지 않습니다.
백그라운드 때는 잘 들어오는데 kill 일떄는 안들어오네요 ㅠㅠ 뭔가 따로 해줘야되나요?? 그리고 알림 내용이 json그대로 들어오는데 잘라서 sendnotification에 넣어야 되나요?
pushman 을 사용해서 위와 같이 보낼 경우 401 에러가 발생합니다.. 헤더쪽에 말씀하신대로 content-Type 과 authorization 정의해줬구여 authorizatino 의 value 값은 key=AlzaSy..으로 제쪽 firebase의 API Key를 갔다 넣었구여 왜 그럴까여..?
답변 감사합니다. 일단 핑거푸시로 진행 중 이였는데 그쪽도 초보에맞는 가이드가 없어서 포기 하려구요. 그냥 한규호님이 올려주신 FCM으로만 사용해야 할것 같네요. 좋은 포스팅 감사했었습니다. 항상 건승하세요. 나중에 시간 되시면 관련 포스팅 기대 하겠습니다.
private void sendPost() throws Exception { String url = "https://fcm.googleapis.com/fcm/send"; URL obj = new URL(url); HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("content-type", "application/json"); con.setRequestProperty("authorization", "key=api키"); String urlParameters = "{\"data\" : {\"message\" : {\"title\":\"test\",\"content\":\"testcontent\",\"imgUrl\":\"\",\"link\":\"\"}},\"to\" : \"/topics/noticeMsg\"}"; // Send post request con.setDoOutput(true); DataOutputStream wr = new DataOutputStream(con.getOutputStream()); wr.writeBytes(urlParameters); wr.flush(); wr.close(); int responseCode = con.getResponseCode(); System.out.println("\nSending 'POST' request to URL : " + url); System.out.println("Post parameters : " + urlParameters); System.out.println("Response Code : " + responseCode); BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); //print result System.out.println(response.toString()); } 이런식으로 하면 될거 같긴 한데 테스트는 못해봤습니다. net.sf.json을 사용 중이시라면 파라미터를 JSONObject로 만들어서 보내도 될거같습니다.
참 자바스트립트 때문에 버철스튜디오? 그것도 깔아서 해보려 했으나, 끝까지 포스팅 한 곳이 없어 지식이 부족한 저에게는 너무 어렵더라구요. 염치 불구 하고 이렇게 문의 하는 것은, 포스팅을 쭉 쫒아 왔고 그래서 기본 코딩이, 이 블러그와 일치합니다. 그래서 더욱 더 이곳에성의 가르침을 원합니다. 구글링으로는 조각조각 나눠져 있었서 저의 지식으로는 이해가 부족합니다. 겨우 안드로이드 만 조각을 대충 맞출 수 있는 단계에 있습니다. 다시한번 부탁드립니다.
자바로 구현하는 방법은 어떻게 해야 하는 건가요? 구글링으로 아무리해도 무지해서인지... 너무 힘드네요. 대체적인 의견이 앱자체에서는 공지시 깨울수 없다고 하더라구요. 그래서 이렇게 염치 불구하고 자세한 포스팅을 부탁드립니다.
POSTMAN 관련해서 더 자세한 포스팅 부탁 해도 될까요? 최근에 배우기 시작해서 겨우 웹뷰로 어플 잘따라 가고 있었으나, 포스트맨에서 걸리고 있습니다. 사실 푸시라는게 앱이 꺼져 있는 상태에서 발송 즉 발송 알림음이 안 된다면 의미가 없는 것 같아서 이렇게 부탁드립니다. ㅠㅠ
박진현님 위에 글에 나와 있듯이 fcm api를 이용하면 콘솔을 이용하지 않고 메세지를 보낼 수 있습니다. 위에 있는 function sendTopicMessage()로 시작하는 코드가 fcm api를 이용하는 nodejs코드 입니다. 원하는 시점에서 sendTopicmessage()를 호출 하시면 콘솔 없이 전송됩니다.
Seungick Jang님 강제종료시에는 안되는 상태가 맞습니다 관련해서는 따로 처리를 해줘야 될듯 싶습니다. 좀 찾아보니 강제 종료시에는 프로세스를 다시 시작하는 방법으로 해야될것 같습니다. https://www.quora.com/How-does-WhatsApp-or-Gmail-receive-notification-even-after-force-closing-them
안녕하세요 ! 설 잘 보내셨는지요 ㅎㅎㅎ.. 참 많이 도움이 되고 있습니다 ! 다만, 질문을 드릴게 있습니다. 작성해주신 글 덕분에 Firebase 콘솔을 이용해서 정상적으로 메시지를 보낼 수 있습니다! 그런데 혹시 node.js 서버 자체에서 바로 푸쉬를 할 수 있는 기능이 없을까요? 즉, Firebase Console 이용없이 보내고 싶습니다
좋은 글 감사드립니다. 저에게 큰 도움이 되었습니다. 그리고 질문이 하나 있습니다. 알림이 foreground나 background, 슬립 상태에서는 수신이 매우 잘 됩니다. 그런데, 프로그램이 완전히 종료된 상태 (강제종료) 에서는 메시지 수신이 안되던데, 이게 특정 폰의 문제일까요? 아니면 안드로이드 자체의 문제일까요? 이 문제로 몇일째 고생중입니다. ㅠㅠ
여기까지 완전 팔로업 하기 쉽게 써주셔서 너무 감사합니다 ㅠㅠ JSONobject 형식으로 노티 받네요. 그럼 게시판의 (3)알림창 설정이랑 url이동 안드로이드 스튜디오에 나온것처럼 똑같이 설정하면 되는거죠 ???
답변 주셔서 너무 반갑고 또 감사합니다 ! 근데 제가 너무 아는게 없고 이쪽 분야는 처음이라서 그런지 도통 postman 쪽으로 보내는 방법만 그나마 배우게 되었고 전혀 다른 부분은 알고 있질 못하네요 ㅠ 혹시 postman으로 푸시알림 클릭시 지정한 url로 이동하는법과 이미지 올리는 방법은 없을까요..? 그것이 궁극적인 목표여서 설명대로 node.js를 통해서라도 해보려고 node.js 서버 만드는 법부터 배워보고 있었는데, 전혀 갈피를 못잡는것 같아서 여쭈어 본거였거든요 .. 일단 알려주신 방법들로 해보겠습니다!
자바에서 post로 호출하는 방법 아래 주소에 올려놓았습니다. https://trandent.com/board/Spring/detail/754 아래 규격에 맞게 header 세팅하고 파라미터 정의해서 날리면 될걸로 보입니다 https://fcm.googleapis.com/fcm/send Content-Type:application/json Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA { "to": "/topics/foo-bar", "data": { "message": "This is a Firebase Cloud Messaging Topic Message!", } }
저 방식은 node.js를 예로 들어서 설명을 한거구요 만약 jquery를 사용하신다면 $.ajax를 통해서 호출 하셔도 됩니다 지금 말씀하시는건 서버상에서 바로 호출하시는걸 말씀하시는건가요?
푸시노티를 만들려고 계속 팔로업 하던 학생입니다. fcm쪽에서 푸시를 보내는건 확인하였습니다. 그런데 nodejs 를 통한 api 호출이라고 하셔서 저 코드를 자바로 저장해서 node 파일면.js 식으로 호출하려하였는데 무반응인데 혹시 제가 잘못된길로 가고있는건가요 몇일째 헤매고 있네요 ㅠ 팁좀 부탁드립니다
질문하나만 드려도 될까요? 앱을 실행중인 어플리케이션에서 종료하게 되면 (프로세스 kill) 푸시를 api통해서 보내도 받지 못하는데, 다른 상황에서는 잘 동작 합니다. 혹시 이런 증상의 해결 방법이 있을까요? ㅠㅠ 제가 시도해본 방법으로는 FirebaseMessagingService를 메인 액티비티에서 시작하고 FirebaseMessagingService.java 에서 onDestroy() 로 서비스를 재시작 해보려고 했으나, 해당 메소드는 안타더라구요.. 작성자님께서는 프로세스가 kill된 상태에서도 동작하시나요 혹시..