android - 在 Firebase 中,如何只向特定的人发送消息

标签 android firebase

我正在使用 firebase 创建一个聊天应用程序,现在任何使用此应用程序的人都可以发送和接收消息,这意味着没有隐私,如果一个人发送一条消息,所有用户都可以看到那条消息。

我想向特定的人发送消息,需要一对一聊天。如何做到这一点?

是否有可用的示例代码?

下面给出代码。

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 {

    }
}

最佳答案

当您从 Firebase 发送消息时,只需输入此人的 InstanceID,这样消息就可以只发送给特定的人。

HTTP POST 请求采用以下格式:

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..."
}

“to” 属性识别消息将发送到的 InstanceId。它不会发送给所有用户。

只需放置您要向其发送消息的个人应用的 InstanceId token

关于android - 在 Firebase 中,如何只向特定的人发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38259387/

相关文章:

android - Android 上的 Facebook : target app doesn't open when clicking on link

android - 如何将 SHA-1 添加到 Android 应用程序

firebase - 如何修改 FirebaseSimpleLogin 管理的用户属性?

java - Android应用程序登录抽屉导航无法点击 fragment

android - 无法解析静态字段 1868

android - 如何知道 Firebase DataSnapshot 何时在服务器端持久化

android - Glide Gradle和FirebaseUI无法同步

javascript - 测试 Firebase 连接是否成功

java - android - 为什么我的 editText 不显示?

android - Android 中的 GROUP BY 子句(ICS 及以上)