Sachin Varma
Sachin Varma

Reputation: 2235

In Firebase,how to send message to a particular person only

I am creating a chat application using firebase, now it is in a condition that anyone using this app can send and receive message,that means no privacy,if a person sends a message all users can see that message.

I want to send message to a particular person,one to one chat is needed.How to do that?

Is there any example codes available ?

Below the codes are give.

public class SignInActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener,
    View.OnClickListener {
private FirebaseAuth.AuthStateListener mAuthListener;
private static final String TAG = "SignInActivity";
private static final int RC_SIGN_IN = 9001;
private SignInButton mSignInButton;
private Button but;
private Button buts;
private Button aura;
public String names;
public EditText email;
public EditText password;
public EditText name;
private SessionManager mSessionManager;
private FirebaseAuth mAuth;
private FirebaseUser mFirebaseUser;



private static final String TAG_USER = "user";
private static final String TAG_ID = "id";


JSONArray user = null;
private GoogleApiClient mGoogleApiClient;
private FirebaseAuth mFirebaseAuth;
String user_id="",pass="";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sign_in);
     email=(EditText)findViewById(R.id.emails);

    name=(EditText)findViewById(R.id.uname);
    password=(EditText)findViewById(R.id.passwords);


    but=(Button)findViewById(R.id.create);
    buts=(Button)findViewById(R.id.creates);
    aura=(Button)findViewById(R.id.aura);
    Firebase.setAndroidContext(getBaseContext());

    mAuth = FirebaseAuth.getInstance();
    buts.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            user_id= email.getText().toString();
            pass= password.getText().toString();

           signIn(user_id,pass);

        }
    });

    but.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            user_id= email.getText().toString();
           pass= password.getText().toString();
            names=name.getText().toString();
            createAccount(user_id,pass);

        }
    });
    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {

                Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
            } else {

                Log.d(TAG, "onAuthStateChanged:signed_out");
            }

            updateUI(user);

        }
    };

    mSignInButton = (SignInButton) findViewById(R.id.sign_in_button);


    mSignInButton.setOnClickListener(this);

    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail()
            .build();
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();


    mFirebaseAuth = FirebaseAuth.getInstance();
}

private void handleFirebaseAuthResult(AuthResult authResult) {
    if (authResult != null) {

        FirebaseUser user = authResult.getUser();
        Toast.makeText(this, "Welcome " + user.getEmail(), Toast.LENGTH_SHORT).show();


        startActivity(new Intent(this, MainActivity.class));
    }
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.sign_in_button:
            signIn();

            break;
        default:
            return;
    }
}

private void signIn() {
    Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
    startActivityForResult(signInIntent, RC_SIGN_IN);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);


    if (requestCode == RC_SIGN_IN) {
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (result.isSuccess()) {

            GoogleSignInAccount account = result.getSignInAccount();
            firebaseAuthWithGoogle(account);
            Log.e(TAG, "Google Sign In Successfull.");
        } else {

            Log.e(TAG, "Google Sign In failed.");
        }
    }
}

private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
    Log.d(TAG, "firebaseAuthWithGooogle:" + acct.getId());
    AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
    mFirebaseAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());


                    if (!task.isSuccessful()) {
                        Log.w(TAG, "signInWithCredential", task.getException());
                        Toast.makeText(SignInActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                    } else {
                        startActivity(new Intent(SignInActivity.this, MainActivity.class));
                        finish();
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    Log.d(TAG, "onConnectionFailed:" + connectionResult);
    Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show();
}

@Override
public void onStart() {
    super.onStart();
    mAuth.addAuthStateListener(mAuthListener);
}

public void onStop() {
    super.onStop();
    if (mAuthListener != null) {
        mAuth.removeAuthStateListener(mAuthListener);
    }
}

private void createAccount(String email, String password) {
    Log.d(TAG, "createAccount:" + email);
    if (!validateForm()) {
        return;
    }


    mAuth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful());

                    model m=new model();

                    if (!task.isSuccessful()) {
                        Toast.makeText(SignInActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                    }


                }
            });

}
private boolean validateForm() {
    boolean valid = true;

    String emails = email.getText().toString();
    if (TextUtils.isEmpty(emails)) {
       email.setError("Required.");
        valid = false;
    } else {
       email.setError(null);
    }

    String passwords = password.getText().toString();
    if (TextUtils.isEmpty(passwords)) {
        password.setError("Required.");
        valid = false;
    } else {
       password.setError(null);
    }

    return valid;
}

private void updateUI(FirebaseUser user) {

    if (user != null) {

       View.VISIBLE);
    } else {

    }
}
private void signIn(String email, String password) {
    Log.d(TAG, "signIn:" + email);
    if (!validateForm()) {
        return;
    }




    mAuth.signInWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    Log.d(TAG, "signInWithEmail:onComplete:" + task.isSuccessful());
                    Bundle b=new Bundle();
                    b.putString("names",user_id);
                    Log.i("test",user_id+"");
                    Intent i=new Intent(SignInActivity.this, MainActivity.class);
                    i.putExtras(b);
                    startActivity(i);


                    finish();

                    if (!task.isSuccessful()) {
                        Log.w(TAG, "signInWithEmail", task.getException());
                        Toast.makeText(SignInActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                    }


                }
            });

}

}

public class MainActivity extends AppCompatActivity implements
    GoogleApiClient.OnConnectionFailedListener

{

public static class MessageViewHolder extends RecyclerView.ViewHolder {
    public TextView messageTextView;
    public TextView messengerTextView;
    public CircleImageView messengerImageView;

    public MessageViewHolder(View v) {
        super(v);
        messageTextView = (TextView) itemView.findViewById(R.id.messageTextView);
        messengerTextView = (TextView) itemView.findViewById(R.id.messengerTextView);
        messengerImageView = (CircleImageView) itemView.findViewById(R.id.messengerImageView);
    }
}

private static final String TAG = "MainActivity";
public static final String MESSAGES_CHILD = "messages";
private static final int REQUEST_INVITE = 1;
public static final int DEFAULT_MSG_LENGTH_LIMIT = 10;
public static final String ANONYMOUS = "anonymous";
private static final String MESSAGE_SENT_EVENT = "message_sent";
private String mUsername;
private String mPhotoUrl;
private SharedPreferences mSharedPreferences;
private DatabaseReference mDatabase;
private Button mSendButton;
private RecyclerView mMessageRecyclerView;
private LinearLayoutManager mLinearLayoutManager;
private FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder> mFirebaseAdapter;
private ProgressBar mProgressBar;
private DatabaseReference mFirebaseDatabaseReference;
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private FirebaseAnalytics mFirebaseAnalytics;
private EditText mMessageEditText;
 private String nameString;
private FirebaseRemoteConfig mFirebaseRemoteConfig;
private GoogleApiClient mGoogleApiClient;
private Uri uri;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);




    mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();


    if(mFirebaseUser!=null){
        mUsername = mFirebaseUser.getDisplayName();
        uri= mFirebaseUser.getPhotoUrl();
        try{
            mPhotoUrl=uri.toString();
        }catch (Exception e){

        }



    }else{
        startActivity(new Intent(this, SignInActivity.class));
        finish();
        //return;
    }
    mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    Bundle b=getIntent().getExtras();

    if(b!=null)
    {
        nameString = b.getString("names");
    }
   /* if (mFirebaseUser == null) {
        // Not signed in, launch the Sign In activity
       *//*  mUsername = mFirebaseUser.getDisplayName();
        mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();*//*
        mUsername = mFirebaseUser.getDisplayName();
        Log.i(">>>Name",""+mUsername);
        startActivity(new Intent(this, SignInActivity.class));
        finish();
        return;
    } else {
        Toast.makeText(MainActivity.this,"NULL",Toast.LENGTH_LONG).show();
       *//* mUsername = mFirebaseUser.getDisplayName();
        mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();*//*

    }*/

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API)
            .build();

    mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
    mMessageRecyclerView = (RecyclerView) findViewById(R.id.messageRecyclerView);
    mLinearLayoutManager = new LinearLayoutManager(this);
    mLinearLayoutManager.setStackFromEnd(true);

    mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
    mFirebaseAdapter = new FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder>(
            FriendlyMessage.class,
            R.layout.item_message,
            MessageViewHolder.class,
            mFirebaseDatabaseReference.child(MESSAGES_CHILD)) {

        @Override
        protected void populateViewHolder(MessageViewHolder viewHolder, FriendlyMessage friendlyMessage, int position) {
            mProgressBar.setVisibility(ProgressBar.INVISIBLE);
            viewHolder.messageTextView.setText(friendlyMessage.getText());
            if(friendlyMessage.getName()==null)
            {
                model m=new model();

                viewHolder.messengerTextView.setText(nameString);
                Log.i("name",nameString+"");
            }
            else{
                viewHolder.messengerTextView.setText(friendlyMessage.getName());
            }

            if (friendlyMessage.getPhotoUrl() == null) {
                viewHolder.messengerImageView.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,
                        R.drawable.ic_account_circle_black_36dp));
            } else {
                Glide.with(MainActivity.this)
                        .load(friendlyMessage.getPhotoUrl())
                        .into(viewHolder.messengerImageView);
            }
        }
    };

    mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            super.onItemRangeInserted(positionStart, itemCount);
            int friendlyMessageCount = mFirebaseAdapter.getItemCount();
            int lastVisiblePosition = mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
            // If the recycler view is initially being loaded or the user is at the bottom of the list, scroll
            // to the bottom of the list to show the newly added message.
            if (lastVisiblePosition == -1 ||
                    (positionStart >= (friendlyMessageCount - 1) && lastVisiblePosition == (positionStart - 1))) {
                mMessageRecyclerView.scrollToPosition(positionStart);
            }
        }
    });

    mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
    mMessageRecyclerView.setAdapter(mFirebaseAdapter);

    mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);


    mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();


    FirebaseRemoteConfigSettings firebaseRemoteConfigSettings =
            new FirebaseRemoteConfigSettings.Builder()
                    .setDeveloperModeEnabled(true)
                    .build();

    // Define default config values. Defaults are used when fetched config values are not
    // available. Eg: if an error occurred fetching values from the server.
    Map<String, Object> defaultConfigMap = new HashMap<>();
    defaultConfigMap.put("friendly_msg_length", 10000L);

    // Apply config settings and default values.
    mFirebaseRemoteConfig.setConfigSettings(firebaseRemoteConfigSettings);
    mFirebaseRemoteConfig.setDefaults(defaultConfigMap);

    // Fetch remote config.
    fetchConfig();

    mMessageEditText = (EditText) findViewById(R.id.messageEditText);

    mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(mSharedPreferences
            .getInt(CodelabPreferences.FRIENDLY_MSG_LENGTH, DEFAULT_MSG_LENGTH_LIMIT))});
    mMessageEditText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            if (charSequence.toString().trim().length() > 0) {
                mSendButton.setEnabled(true);
            } else {
                mSendButton.setEnabled(false);
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {
        }
    });

    mSendButton = (Button) findViewById(R.id.sendButton);
    mSendButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
           // submitPost();
            FriendlyMessage friendlyMessage = new FriendlyMessage(mMessageEditText.getText().toString(), mUsername,
                    mPhotoUrl);
            mFirebaseDatabaseReference.child(MESSAGES_CHILD).push().setValue(friendlyMessage);
            mMessageEditText.setText("");
            mFirebaseAnalytics.logEvent(MESSAGE_SENT_EVENT, null);
        }
    });
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.invite_menu:
            sendInvitation();
            return true;
        case R.id.crash_menu:
            FirebaseCrash.logcat(Log.ERROR, TAG, "crash caused");
            causeCrash();
            return true;
        case R.id.sign_out_menu:
           // mFirebaseAuth.signOut();
            //Auth.GoogleSignInApi.signOut(mGoogleApiClient);
            //mFirebaseUser = null;
            //mUsername = ANONYMOUS;
            //mPhotoUrl = null;
            mFirebaseAuth.signOut();
            updateUI(null);
            startActivity(new Intent(this, SignInActivity.class));
            return true;
        case R.id.fresh_config_menu:
            fetchConfig();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

private void causeCrash() {
    throw new NullPointerException("Fake null pointer exception");
}

private void sendInvitation() {
    Intent intent = new AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
            .setMessage(getString(R.string.invitation_message))
            .setCallToActionText(getString(R.string.invitation_cta))
            .build();
    startActivityForResult(intent, REQUEST_INVITE);
}

// Fetch the config to determine the allowed length of messages.
public void fetchConfig() {
    long cacheExpiration = 3600; // 1 hour in seconds
    // If developer mode is enabled reduce cacheExpiration to 0 so that each fetch goes to the
    // server. This should not be used in release builds.
    if (mFirebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
        cacheExpiration = 0;
    }
    mFirebaseRemoteConfig.fetch(cacheExpiration)
            .addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    // Make the fetched config available via FirebaseRemoteConfig get<type> calls.
                    mFirebaseRemoteConfig.activateFetched();
                    applyRetrievedLengthLimit();
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    // There has been an error fetching the config
                    Log.w(TAG, "Error fetching config: " + e.getMessage());
                    applyRetrievedLengthLimit();
                }
            });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.d(TAG, "onActivityResult: requestCode=" + requestCode + ", resultCode=" + resultCode);

    if (requestCode == REQUEST_INVITE) {
        if (resultCode == RESULT_OK) {
            // Use Firebase Measurement to log that invitation was sent.
            Bundle payload = new Bundle();
            payload.putString(FirebaseAnalytics.Param.VALUE, "inv_sent");

            // Check how many invitations were sent and log.
            String[] ids = AppInviteInvitation.getInvitationIds(resultCode, data);
            Log.d(TAG, "Invitations sent: " + ids.length);
        } else {
            // Use Firebase Measurement to log that invitation was not sent
            Bundle payload = new Bundle();
            payload.putString(FirebaseAnalytics.Param.VALUE, "inv_not_sent");
            mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SHARE, payload);

            // Sending failed or it was canceled, show failure message to the user
            Log.d(TAG, "Failed to send invitation.");
        }
    }
}

/**
 * Apply retrieved length limit to edit text field. This result may be fresh from the server or it may be from
 * cached values.
 */
private void applyRetrievedLengthLimit() {
    Long friendly_msg_length = mFirebaseRemoteConfig.getLong("friendly_msg_length");
    mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(friendly_msg_length.intValue())});
    Log.d(TAG, "FML is: " + friendly_msg_length);
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.d(TAG, "onConnectionFailed:" + connectionResult);
}
private void submitPost() {

    final String title = "Hai";
    final String body = "hello";
    final String user;


    // Title is required
    if (TextUtils.isEmpty(title)) {
        //.setError(REQUIRED);
        return;
    }

    // Body is required
    if (TextUtils.isEmpty(body)) {
       // mBodyField.setError(REQUIRED);
        return;
    }

    // [START single_value_read]
    //final String userId = getUid();
    mDatabase.child("users").child(userId).addListenerForSingleValueEvent(
            new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    // Get user value
                    User user = dataSnapshot.getValue(User.class);

                    // [START_EXCLUDE]
                    if (user == null) {
                        // User is null, error out
                        Log.e(TAG, "User " + userId + " is unexpectedly null");
                        Toast.makeText(MainActivity.this,
                                "Error: could not fetch user.",
                                Toast.LENGTH_SHORT).show();
                    } else {
                        // Write new post
                        writeNewPost(userId, user.username, title, body);
                    }

                    // Finish this Activity, back to the stream
                    finish();
                    // [END_EXCLUDE]
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Log.w(TAG, "getUser:onCancelled", databaseError.toException());
                }
            });
    // [END single_value_read]
}
private void writeNewPost(String userId, String username, String title, String body) {

    String key = mDatabase.child("posts").push().getKey();
    Post post = new Post(userId, username, title, body);
    Map<String, Object> postValues = post.toMap();

    Map<String, Object> childUpdates = new HashMap<>();
    childUpdates.put("/posts/" + key, postValues);
    childUpdates.put("/user-posts/" + userId + "/" + key, postValues);

    mDatabase.updateChildren(childUpdates);
}
private void updateUI(FirebaseUser user) {

    if (user != null) {

    } else {

    }
}

}

Upvotes: 1

Views: 2170

Answers (1)

Saini
Saini

Reputation: 734

When you are sending Message from Firebase, Just put the person's InstanceID so that message can be sent to the particular person only.

The HTTP POST REQUEST is in the following format:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

The "to" attribute recognises the InstanceId to whom the message will be sent. It will not be sent to all the users.

Just put the InstanceId token of the person app to whom you want to send the message.

Upvotes: 1

Related Questions