Dim
Dim

Reputation: 4807

Client to client short messaging

I am implementing small communication between two clients in Android. Currently I am using Firebase Realtime Database that holding all my users with push tokens.

I use Firebase Cloud Messaging to send push messages from one to other using REST embedded in my code. This is not so good practice due to that I need to save my server key hardcoded in the app. I thought about using XMPP but its bit overkill for what I need.

I need small communication between the users for one asking the other for their location and gets the coordinates in return. The messages do not needed to be saved on server and it just one time request and response. As I previously said I am currently using FCM for that.

Can you suggest maybe better solution for this, without XMPP?

Upvotes: 1

Views: 246

Answers (3)

Grimthorr
Grimthorr

Reputation: 6926

It seems like using Firebase Cloud Messaging would be the preferable method. However, if that isn't working for you, we could leverage the Realtime Database to do this, although it won't be strictly client-to-client.

As an example: imagine we have 2 users with the UIDs of user1 and user2. The database could be structured so that each user has their own list under the /requests and /responses nodes:

{
  "requests": {
    "user1": {},
    "user2": {}
  },
  "responses": {
    "user1": {},
    "user2": {}
  }
}

In the scenario where user2 wants to request the location of user1, the clients would follow the below flow:

flow

For Android, this would work something like:

private FirebaseDatabase database = FirebaseDatabase.getInstance();
private FirebaseAuth auth = FirebaseAuth.getInstance();
private String myUserId;

private void setup() {
    if (auth.getCurrentUser() == null) { // User must be signed-in
        finish();
        return;
    }

    myUserId = auth.getCurrentUser().getUid();

    DatabaseReference requestsRef = database.getReference("requests").child(myUserId);
    DatabaseReference responsesRef = database.getReference("responses").child(myUserId);

    requestsRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            handleRequest(dataSnapshot.getKey());
            dataSnapshot.getRef().removeValue(); // Delete the request once it's been handled
        }
        // ...
    });

    responsesRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            String from = dataSnapshot.getKey();
            String coordinates = dataSnapshot.getValue(String.class);
            if (from != null && coordinates != null) handleResponse(from, coordinates);
            dataSnapshot.getRef().removeValue(); // Delete the response once it's been handled
        }
        // ...
    });
}

private void handleResponse(String from, String coordinates) {
    Toast.makeText(this, String.format("User: %s is located at: %s", from, coordinates), Toast.LENGTH_SHORT).show();
}

private void handleRequest(String from) {
    Toast.makeText(this, String.format("User: %s wants to know our location", from), Toast.LENGTH_SHORT).show();
    sendResponse(from);
}

private void sendResponse(String to) {
    String myCoordinates = "37.4220° N, 122.0841° W"; // Example, this will need implementing
    database.getReference("/responses").child(to).child(myUserId).setValue(myCoordinates);
}

private void sendRequest(String to) {
    database.getReference("/requests").child(to).child(myUserId).setValue(true);
}

With this example, both user's clients will first call setup() to begin listening for requests and responses.

Then, to request a user's coordinates, call sendRequest() from one client. The other client will receive this request in the handleRequest() method and send their coordinates to the database. Finally, the requesting client will receive this response in the handleResponse() method.

This probably isn't quite what you're looking for, but it was a fun exercise for me, so I wanted to share it anyway.

Upvotes: 1

Ashish Chaugule
Ashish Chaugule

Reputation: 1593

now you can use firebase realtime database and cloud firestore database no need to FCM you will get realtime and offline as well

https://code.tutsplus.com/tutorials/how-to-create-an-android-chat-app-using-firebase--cms-27397

enjoy

Upvotes: 1

hossam scott
hossam scott

Reputation: 478

SOCKET is very simple and a lot of big corporations are using it.

With Socket client you can enable Send and Receive method if the commutations will be 2 ways inside your application.

For Example: To send your Lat & Long use

String location = "123123,123123"
mSocket.emit("Update", location);

And to receive other user new location place below code inside your OnCreate:

mSocket.on("Update", GettingUpdate);
mSocket.connect();

And Do your logic inside GettingUpdate Method

private Emitter.Listener GettingUpdate= new Emitter.Listener() {
    @Override
    public void call(final Object.. args) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                JSONObject data = (JSONObject) args[0];
                String location;
                try {
                    location= data.getString("location");
                } catch (JSONException e) {
                    return;
                }

               Toast.makeText(getActivity(), message,Toast.LENGTH_LONG).show();

            }
        });
    }
};

you can find example at documentation

Android project example : Github

Upvotes: 1

Related Questions