UFO ET IT

Firebase 클라우드 메시징을 사용하여 장치 대 장치 메시지를 보내는 방법은 무엇입니까?

ufoet 2020. 11. 8. 11:38
반응형

Firebase 클라우드 메시징을 사용하여 장치 대 장치 메시지를 보내는 방법은 무엇입니까?


문서를 검색 한 후 외부 서버를 사용하지 않고 FCM을 사용하여 장치 대 장치 메시지를 보내는 방법에 대한 정보를 찾을 수 없습니다.

예를 들어 채팅 애플리케이션을 만드는 경우 사용자가 항상 온라인 상태가 아니기 때문에 읽지 않은 메시지에 대한 푸시 알림을 사용자에게 보내야하며 항상 연결되는 백그라운드에서 지속적인 서비스를 사용할 수 없습니다. 리소스가 너무 많기 때문에 실시간 데이터베이스입니다.

그러면 특정 사용자 "B"가 그 / 그녀에게 채팅 메시지를 보낼 때 사용자 "A"에게 푸시 알림을 보내려면 어떻게해야합니까? 이를 위해 외부 서버가 필요합니까 아니면 Firebase 서버로만 수행 할 수 있습니까?


업데이트 : 이제 푸시 알림 처리를위한 서버로 firebase 클라우드 기능을 사용할 수 있습니다. 여기 에서 문서를 확인 하십시오.

============

문서에 따르면 장치 간 통신에서 푸시 알림을 처리하기위한 서버를 구현 해야합니다 .

Firebase 클라우드 메시징을 사용하는 클라이언트 앱을 작성하려면 먼저 다음 기준을 충족하는 앱 서버가 있어야합니다.

...

앱 서버가 FCM 연결 서버와 상호 작용할 수 있도록 설정하는 데 사용할 FCM 연결 서버 프로토콜을 결정해야합니다. 클라이언트 애플리케이션에서 업스트림 메시징을 사용하려면 XMPP를 사용해야합니다. 이에 대한 자세한 내용은 FCM 연결 서버 프로토콜 선택을 참조하십시오 .

서버에서 사용자에게 기본 알림 만 보내야하는 경우. 서버리스 솔루션 인 Firebase 알림을 사용할 수 있습니다 .

여기에서 FCM과 Firebase 알림의 비교를 확인하세요. https://firebase.google.com/support/faq/#messaging-difference


필요한 헤더와 데이터가 포함 된 https://fcm.googleapis.com/fcm/send 링크를 사용하여 HTTP POST 요청을하는 것이 도움이되었습니다. 아래 코드 스 니펫 Constants.LEGACY_SERVER_KEY은 로컬 클래스 변수이며 Firebase 프로젝트에서 찾을 수 있습니다 Settings->Cloud Messaging->Legacy Server key. 기기 등록 토큰을 전달해야합니다. 즉 regToken, 여기 에서 참조하는 아래 코드 스 니펫에서 .

이 코드 조각이 작동 하려면 마침내 okhttp 라이브러리 종속성 이 필요 합니다.

public static final MediaType JSON
        = MediaType.parse("application/json; charset=utf-8");
private void sendNotification(final String regToken) {
    new AsyncTask<Void,Void,Void>(){
        @Override
        protected Void doInBackground(Void... params) {
            try {
                OkHttpClient client = new OkHttpClient();
                JSONObject json=new JSONObject();
                JSONObject dataJson=new JSONObject();
                dataJson.put("body","Hi this is sent from device to device");
                dataJson.put("title","dummy title");
                json.put("notification",dataJson);
                json.put("to",regToken);
                RequestBody body = RequestBody.create(JSON, json.toString());
                Request request = new Request.Builder()
                        .header("Authorization","key="+Constants.LEGACY_SERVER_KEY)
                        .url("https://fcm.googleapis.com/fcm/send")
                        .post(body)
                        .build();
                Response response = client.newCall(request).execute();
                String finalResponse = response.body().string();
            }catch (Exception e){
                //Log.d(TAG,e+"");
            }
            return null;
        }
    }.execute();

}

또한 특정 주제에 메시지를 보내려면 다음 regToken과 같이 json으로 바꾸십시오 .

json.put("to","/topics/foo-bar")

AndroidManifest.xml에 INTERNET 권한을 추가하는 것을 잊지 마십시오.

중요 :-위 코드를 사용하면 서버 키가 클라이언트 응용 프로그램에 있습니다. 누군가가 애플리케이션을 파고 들어 서버 키를 얻어서 사용자에게 악성 알림을 보낼 수 있기 때문에 위험합니다.


예, 서버 없이도 가능합니다. 장치 그룹 클라이언트 측을 만든 다음 그룹에서 메시지를 교환 할 수 있습니다. 그러나 제한 사항이 있습니다.

  1. 기기에서 동일한 Google 계정을 사용해야합니다.
  2. 우선 순위가 높은 메시지를 보낼 수 없습니다.

참조 : Firebase 문서 "Android 클라이언트 앱에서 기기 그룹 관리"섹션 참조


Volly Jsonobject 요청을 사용하여 할 수 있습니다 ....

먼저 다음 단계를 따르십시오.

1 기존 서버 키를 복사하여 Legacy_SERVER_KEY 로 저장

레거시 서버 키

당신은 얻는 방법을 그림에서 볼 수 있습니다

2 발리 의존성이 필요합니다

'com.mcxiaoke.volley : library : 1.0.19'컴파일

여기에 이미지 설명 입력

푸시 보내기 코드 :-

    private void sendFCMPush() {

            String Legacy_SERVER_KEY = YOUR_Legacy_SERVER_KEY;
            String msg = "this is test message,.,,.,.";
            String title = "my title";
            String token = FCM_RECEIVER_TOKEN;

            JSONObject obj = null;
        JSONObject objData = null;
        JSONObject dataobjData = null;

        try {
            obj = new JSONObject();
            objData = new JSONObject();

            objData.put("body", msg);
            objData.put("title", title);
            objData.put("sound", "default");
            objData.put("icon", "icon_name"); //   icon_name image must be there in drawable
            objData.put("tag", token);
            objData.put("priority", "high");

            dataobjData = new JSONObject();
            dataobjData.put("text", msg);
            dataobjData.put("title", title);

            obj.put("to", token);
            //obj.put("priority", "high");

            obj.put("notification", objData);
            obj.put("data", dataobjData);
            Log.e("!_@rj@_@@_PASS:>", obj.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }

            JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, Constants.FCM_PUSH_URL, obj,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            Log.e("!_@@_SUCESS", response + "");
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Log.e("!_@@_Errors--", error + "");
                        }
                    }) {
                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String, String> params = new HashMap<String, String>();
                    params.put("Authorization", "key=" + Legacy_SERVER_KEY);
                    params.put("Content-Type", "application/json");
                    return params;
                }
            };
            RequestQueue requestQueue = Volley.newRequestQueue(this);
            int socketTimeout = 1000 * 60;// 60 seconds
            RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
            jsObjRequest.setRetryPolicy(policy);
            requestQueue.add(jsObjRequest);
}

그냥 호출 sendFCMPush () ;


1) 동일한 주제 이름을 구독하십시오. 예 :

  • ClientA.subcribe ( "to / topic_users_channel")
  • ClientB.subcribe ( "to / topic_users_channel")

2) 애플리케이션 내에서 메시지 보내기

GoogleFirebase : 주제 메시지를 보내는 방법


알림을 보낼 장치의 fcm (gcm) 토큰이있는 경우. 알림을 보내기위한 포스트 요청 일뿐입니다.

https://github.com/prashanthd/google-services/blob/master/android/gcm/gcmsender/src/main/java/gcm/play/android/samples/com/gcmsender/GcmSender.java


Retrofit을 사용할 수 있습니다. 주제 뉴스를 구독하세요. 한 장치에서 다른 장치로 알림을 보냅니다.

public void onClick(View view) {

    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    httpClient.addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request original = chain.request();

            // Request customization: add request headers
            Request.Builder requestBuilder = original.newBuilder()
                    .header("Authorization", "key=legacy server key from FB console"); // <-- this is the important line
            Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    });

    httpClient.addInterceptor(logging);
    OkHttpClient client = httpClient.build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://fcm.googleapis.com")//url of FCM message server
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())//use for convert JSON file into object
            .build();

    // prepare call in Retrofit 2.0
    FirebaseAPI firebaseAPI = retrofit.create(FirebaseAPI.class);

    //for messaging server
    NotifyData notifydata = new NotifyData("Notification title","Notification body");

Call<Message> call2 = firebaseAPI.sendMessage(new Message("topic or deviceID", notifydata));

    call2.enqueue(new Callback<Message>() {
        @Override
        public void onResponse(Call<Message> call, Response<Message> response) {

            Log.d("Response ", "onResponse");
            t1.setText("Notification sent");

        }

        @Override
        public void onFailure(Call<Message> call, Throwable t) {
            Log.d("Response ", "onFailure");
            t1.setText("Notification failure");
        }
    });
}

POJO

public class Message {
String to;
NotifyData notification;

public Message(String to, NotifyData notification) {
    this.to = to;
    this.notification = notification;
}

}

public class NotifyData {
String title;
String body;

public NotifyData(String title, String body ) {

    this.title = title;
    this.body = body;
}

}

및 FirebaseAPI

public interface FirebaseAPI {

@POST("/fcm/send")
Call<Message> sendMessage(@Body Message message);

}

이제 Google Cloud Functions를 사용하면 앱 서버없이 기기에서 기기로 푸시 알림을 보낼 수 있습니다.

Google Cloud Functions 의 관련 페이지 에서 :

개발자는 Cloud Functions를 사용하여 사용자의 참여를 유지하고 앱 관련 정보를 최신 상태로 유지할 수 있습니다. 예를 들어 사용자가 앱에서 서로의 활동을 팔로우 할 수있는 앱을 생각해보십시오. 이러한 앱에서 새로운 팔로워를 저장하기 위해 실시간 데이터베이스 쓰기에 의해 트리거되는 함수는 FCM (Firebase Cloud Messaging) 알림을 생성하여 적절한 사용자에게 새로운 팔로워를 확보했음을 알릴 수 있습니다.

예:

  1. 이 함수는 팔로어가 저장된 실시간 데이터베이스 경로에 쓸 때 트리거됩니다.

  2. 이 함수는 FCM을 통해 보낼 메시지를 작성합니다.

  3. FCM이 사용자의 기기로 알림 메시지를 보냅니다.

다음은 Firebase 및 Google Cloud Functions를 사용하여 기기 간 푸시 알림을 보내는 데모 프로젝트 입니다.


이제 Google Cloud Functions를 사용하면 앱 서버없이 기기에서 기기로 푸시 알림을 보낼 수 있습니다. 데이터베이스에 새 메시지가 추가되면 트리거되는 클라우드 기능을 만들었습니다.

그것은이다 node.js코드

'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin'); admin.initializeApp();

exports.sendNotification = functions.database.ref('/conversations/{chatLocation}/{messageLocation}')
  .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();

       const toIDUser = original.toID;
       const isGroupChat = original.isGroupChat;

       if (isGroupChat) {
       const tokenss =  admin.database().ref(`/users/${toIDUser}/tokens`).once('value').then(function(snapshot) {

// Handle Promise
       const tokenOfGroup = snapshot.val()

      // get tokens from the database  at particular location get values 
       const valuess = Object.keys(tokenOfGroup).map(k => tokenOfGroup[k]);

     //console.log(' ____________ddd((999999ddd_________________ ' +  valuess );
    const payload = {
       notification: {
                 title:   original.senderName + " :- ",
                 body:    original.content
    }
  };

  return admin.messaging().sendToDevice(valuess, payload);



}, function(error) {

  console.error(error);
});

       return ;
          } else {
          // get token from the database  at particular location
                const tokenss =  admin.database().ref(`/users/${toIDUser}/credentials`).once('value').then(function(snapshot) {
                // Handle Promise
  // The Promise was "fulfilled" (it succeeded).

     const credentials = snapshot.val()



    // console.log('snapshot ......snapshot.val().name****^^^^^^^^^^^^kensPromise****** :- ', credentials.name);
     //console.log('snapshot.....****snapshot.val().token****^^^^^^^^^^^^kensPromise****** :- ', credentials.token);


     const deviceToken = credentials.token;

    const payload = {
       notification: {
                 title:   original.senderName + " :- ",
                 body:    original.content
    }
  };

  return admin.messaging().sendToDevice(deviceToken, payload);


}, function(error) {

  console.error(error);
});


          }





  return ;


    });

제 경우 에는이 클래스 메시지와 함께 개조사용합니다 .

public class Message {

    private String to;
    private String collapseKey;
    private Notification notification;
    private Data data;

    public Message(String to, String collapseKey, Notification notification, Data data) {
        this.to = to;
        this.collapseKey = collapseKey;
        this.notification = notification;
        this.data = data;
    }

데이터

public class Data {

    private String body;
    private String title;
    private String key1;
    private String key2;

    public Data(String body, String title, String key1, String key2) {
        this.body = body;
        this.title = title;
        this.key1 = key1;
        this.key2 = key2;
    }
}

공고

public class Notification {

    private String body;
    private String title;

    public Notification(String body, String title) {
        this.body = body;
        this.title = title;
    }
}

이 전화

private void sentToNotification() {


            String to = "YOUR_TOKEN";
            String collapseKey = "";
            Notification notification = new Notification("Hello bro", "title23");
            Data data = new Data("Hello2", "title2", "key1", "key2");
            Message notificationTask = new Message(to, collapseKey, notification, data);

            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("https://fcm.googleapis.com/")//url of FCM message server
                    .addConverterFactory(GsonConverterFactory.create())//use for convert JSON file into object
                    .build();

            ServiceAPI api = new retrofit.create(ServiceAPI.class);

            Call<Message> call = api .sendMessage("key=YOUR_KEY", notificationTask);

            call.enqueue(new Callback<Message>() {
                @Override
                public void onResponse(Call<Message> call, retrofit2.Response<Message> response) {
                    Log.d("TAG", response.body().toString());
                }

                @Override
                public void onFailure(Call<Message> call, Throwable t) {

                    Log.e("TAG", t.getMessage());
                }
            });
        }

우리의 서비스

public interface ServiceAPI {
    @POST("/fcm/send")
    Call<Message> sendMessage(@Header("Authorization") String token, @Body Message message);
}

이를 위해 Firebase 실시간 데이터베이스를 사용할 수 있습니다. 채팅을 저장하기위한 데이터 구조를 만들고 두 사용자의 대화 스레드에 대한 관찰자를 추가 할 수 있습니다. 여전히 장치-서버-장치 아키텍처를 수행하지만이 경우 개발자 측에 추가 서버가 없습니다. 이것은 firebase 서버를 사용합니다. 여기에서 튜토리얼을 확인할 수 있습니다 (UI 부분은 무시하지만 채팅 UI 프레임 워크의 좋은 시작점이기도합니다).

Firebase 실시간 채팅


그래서 여기에 아이디어가있었습니다. 참조 : FCM과 GCM에이 메시지를 전달하려는 기기의 토큰을 포함하여 메시지 데이터와 함께 json 게시를 보낼 수있는 http 요청에 대한 endpoit이있는 경우.

그렇다면이 알림이 사용자 B에게 전달되도록 Firebase 서버에 게시물을 보내면 어떨까요? 이해해?

따라서 사용자가 백그라운드에서 앱을 사용하는 경우 알림을 전달하기 위해 메시지를 보내고 통화 게시물과 채팅을합니다. 곧 필요합니다. 나중에 테스트하겠습니다. 당신은 무엇에 대해 말합니까?


가장 간단한 방법 :

void sendFCMPush(String msg,String token) {
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    httpClient.addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request original = chain.request();

            // Request customization: add request headers
            Request.Builder requestBuilder = original.newBuilder()
                    .header("Authorization", "key="+Const.FIREBASE_LEGACY_SERVER_KEY); // <-- this is the important line
            Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    });

    httpClient.addInterceptor(logging);
    OkHttpClient client = httpClient.build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://fcm.googleapis.com/")//url of FCM message server
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())//use for convert JSON file into object
            .build();

    // prepare call in Retrofit 2.0
    FirebaseAPI firebaseAPI = retrofit.create(FirebaseAPI.class);

    //for messaging server
    NotifyData notifydata = new NotifyData("Chatting", msg);

    Call<Message> call2 = firebaseAPI.sendMessage(new Message(token, notifydata));

    call2.enqueue(new Callback<Message>() {
        @Override
        public void onResponse(Call<Message> call, retrofit2.Response<Message> response) {
            Log.e("#@ SUCCES #E$#", response.body().toString());
        }

        @Override
        public void onFailure(Call<Message> call, Throwable t) {

            Log.e("E$ FAILURE E$#", t.getMessage());
        }
    });
}

객체를 만들기위한 클래스 생성 :

public class Message {
String to;
NotifyData data;

public Message(String to, NotifyData data) {
    this.to = to;
    this.data = data;
}
}

객체를 만들기위한 클래스 생성 :

public class Notification {
String title;
String message;
enter code here`enter code here`
public Notification(String title, String message) {
    this.title = title;
    this.message = message;
}
}

참고 URL : https://stackoverflow.com/questions/37435750/how-to-send-device-to-device-messages-using-firebase-cloud-messaging

반응형

'UFO ET IT' 카테고리의 다른 글

파이썬 집합 이해력  (0) 2020.11.08
은 무슨 뜻인가요?  (0) 2020.11.08
정규식을위한 파서 작성  (0) 2020.11.08
Git 원격 / 공유 사전 커밋 후크  (0) 2020.11.08
tomcat-dbcp 대 commons-dbcp  (0) 2020.11.08