如何使用Firebase消息发送一对一消息 [英] How to send one to one message using Firebase Messaging

查看:331
本文介绍了如何使用Firebase消息发送一对一消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试阅读关于如何从一台设备向另一台设备发送消息的官方文档和指南。我已经在实时数据库中保存了这两个设备的注册令牌,因此我有另一个设备的注册令牌。
我尝试了以下的方式发送消息:

$ $ $ $ $ $ $ $ RemoteMessage message = new RemoteMessage.Builder(getRegistrationToken())
.setMessageId(incrementIdAndGet())
.addData(message,Hello)
.build();
FirebaseMessaging.getInstance()。send(message);

但是这不起作用。其他设备不会收到任何消息。我甚至不确定,如果我可以使用上行消息发送进行设备到设备的通信。



PS:我只想知道使用FCM的设备到设备消息是否可行?如果是,那么我使用的代码有一些问题?如果是,那么正确的方法是什么。



更新:

我的问题是询问设备到设备不使用除Firebase以外的任何单独的服务器的消息传递是可能的或不可能的,如果是的话比如何,因为没有关于它的文档。我不明白这里要解释什么?无论如何,我得到的答案,并将更新它作为一个答案,一旦问题重新打开。

解决方案


警告有一个非常重要的原因,我们为什么不在任何地方提到这个方法。这暴露了您在每个客户端设备上放置
的APK服务器密钥。它可以(因此将)从
中拿走,并可能导致滥用您的项目。我强烈建议
不要采用这种方法,除了那些只用
自己的设备的应用程序。 - Frank van Puffelen


好的,所以Frank的回答是正确的: Firebase 本身不支持设备到设备消息。但是这里有一个漏洞。 Firebase服务器不会识别您是从实际的服务器发送请求还是从您的设备进行此操作。

因此,您只需发送发布请求 Firebase 的消息服务器以及服务器密钥。请牢记服务器密钥不应位于设备上,但如果您想使用Firebase消息传递设备到设备的消息传递,则别无选择。

我使用OkHTTP而不是调用Rest API的默认方式。代码是这样的 -

  public static final String FCM_MESSAGE_URL =https://fcm.googleapis.com/fcm/发送; 
OkHttpClient mClient = new OkHttpClient();
public void sendMessage(final JSONArray recipients,final String title,final String body,final String icon,final String message){
$ b $ new AsyncTask< String,String,String>(){
@Override
protected String doInBackground(String ... params){
try {
JSONObject root = new JSONObject();
JSONObject notification = new JSONObject();
notification.put(body,body);
notification.put(title,title);
notification.put(icon,icon);

JSONObject data = new JSONObject();
data.put(message,message);
root.put(通知,通知);
root.put(data,data);
root.put(registration_ids,收件人);

String result = postToFCM(root.toString());
Log.d(TAG,Result:+ result);
返回结果;
catch(Exception ex){
ex.printStackTrace();
}
返回null;

$ b @Override
保护无效onPostExecute(字符串结果){
尝试{
JSONObject resultJson = new JSONObject(result);
int成功,失败;
success = resultJson.getInt(success);
failure = resultJson.getInt(failure);
Toast.makeText(getCurrentActivity(),Message Success:+ success +Message Failed:+ failure,Toast.LENGTH_LONG).show();
} catch(JSONException e){
e.printStackTrace();
Toast.makeText(getCurrentActivity(),Message Failed,Unknown error occurred。,Toast.LENGTH_LONG).show();
}
}
} .execute();


字符串postToFCM(String bodyString)抛出IOException {
RequestBody body = RequestBody.create(JSON,bodyString);
Request request = new Request.Builder()
.url(FCM_MESSAGE_URL)
.post(body)
.addHeader(Authorization,key =+ SERVER_KEY)
.build();
响应响应= mClient.newCall(request).execute();
return response.body()。string();
}

我希望Firebase未来会有更好的解决方案。但在那之前,我认为这是唯一的方法。另一种方法是发送话题消息或群组消息。但这不在问题的范围之内。



更新:

JSONArray是这样定义的 - $ / b>

  JSONArray regArray = new JSONArray(regIds); 

regIds是注册ID的String数组,您要发送此消息给。请记住,注册ID必须始终在一个数组中,即使您希望将其发送给单个收件人。


I have been trying to read the official docs and guides about how to send message from one device to another. I have saved registration token of both devices in the Real Time Database, thus I have the registration token of another device. I have tried the following way to send the message

RemoteMessage message = new RemoteMessage.Builder(getRegistrationToken())
                    .setMessageId(incrementIdAndGet())
                    .addData("message", "Hello")
                    .build();
FirebaseMessaging.getInstance().send(message);

However this is not working. The other device doesn't receive any message. I am not even sure, if I can use upstream message sending to conduct device to device communication.

PS: I just want to know if device-to-device messaging is possible using FCM? If yes, then is the code I used have some issue? If yes, then what is the correct way.

Update:
My question was to ask whether device to device messaging without using any separate server other than firebase could messaging is possible or not, if yes than how, since there's no documentation about it. I do not understand what is left to explain here? Anyways I got the answer and will update it as an answer once the question gets reopened.

解决方案

Warning There is a very important reason why we don't mention this approach anywhere. This exposes your server key in the APK that you put on every client device. It can (and thus will) be taken from there and may lead to abuse of your project. I highly recommend against taking this approach, except for apps that you only put on your own devices. – Frank van Puffelen

Ok, so the answer by Frank was correct that Firebase does not natively support device to device messaging. However there's one loophole in that. The Firebase server doesn't identify whether you have send the request from an actual server or are you doing it from your device.

So all you have to do is send a Post Request to Firebase's messaging server along with the Server Key. Just keep this in mind that the server key is not supposed to be on the device, but there's no other option if you want device-to-device messaging using Firebase Messaging.

I am using OkHTTP instead of default way of calling the Rest API. The code is something like this -

public static final String FCM_MESSAGE_URL = "https://fcm.googleapis.com/fcm/send";
OkHttpClient mClient = new OkHttpClient();
public void sendMessage(final JSONArray recipients, final String title, final String body, final String icon, final String message) {

        new AsyncTask<String, String, String>() {
            @Override
            protected String doInBackground(String... params) {
                try {
                    JSONObject root = new JSONObject();
                    JSONObject notification = new JSONObject();
                    notification.put("body", body);
                    notification.put("title", title);
                    notification.put("icon", icon);

                    JSONObject data = new JSONObject();
                    data.put("message", message);
                    root.put("notification", notification);
                    root.put("data", data);
                    root.put("registration_ids", recipients);

                    String result = postToFCM(root.toString());
                    Log.d(TAG, "Result: " + result);
                    return result;
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(String result) {
                try {
                    JSONObject resultJson = new JSONObject(result);
                    int success, failure;
                    success = resultJson.getInt("success");
                    failure = resultJson.getInt("failure");
                    Toast.makeText(getCurrentActivity(), "Message Success: " + success + "Message Failed: " + failure, Toast.LENGTH_LONG).show();
                } catch (JSONException e) {
                    e.printStackTrace();
                    Toast.makeText(getCurrentActivity(), "Message Failed, Unknown error occurred.", Toast.LENGTH_LONG).show();
                }
            }
        }.execute();
    }

String postToFCM(String bodyString) throws IOException {
        RequestBody body = RequestBody.create(JSON, bodyString);
        Request request = new Request.Builder()
                .url(FCM_MESSAGE_URL)
                .post(body)
                .addHeader("Authorization", "key=" + SERVER_KEY)
                .build();
        Response response = mClient.newCall(request).execute();
        return response.body().string();
    }

I hope Firebase will come with a better solution in future. But till then, I think this is the only way. The other way would be to send topic message or group messaging. But that was not in the scope of the question.

Update:
The JSONArray is defined like this -

JSONArray regArray = new JSONArray(regIds);

regIds is a String array of registration ids, you want to send this message to. Keep in mind that the registration ids must always be in an array, even if you want it to send to a single recipient.

这篇关于如何使用Firebase消息发送一对一消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆