I am using firebase database, but I am newbie with it. I am following this tutorial,
Now, my question is how can I check the email if it is already exist in the database? If email is already there data should not be add to db.
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private TextView txtDetails;
private EditText inputName, inputEmail;
private Button btnSave;
private DatabaseReference mFirebaseDatabase;
private FirebaseDatabase mFirebaseInstance;
private String userId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Displaying toolbar icon
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setIcon(R.mipmap.ic_launcher);
txtDetails = (TextView) findViewById(R.id.txt_user);
inputName = (EditText) findViewById(R.id.name);
inputEmail = (EditText) findViewById(R.id.email);
btnSave = (Button) findViewById(R.id.btn_save);
mFirebaseInstance = FirebaseDatabase.getInstance();
// get reference to 'users' node
mFirebaseDatabase = mFirebaseInstance.getReference("users");
// store app title to 'app_title' node
mFirebaseInstance.getReference("app_title").setValue("Realtime");
// app_title change listener
mFirebaseInstance.getReference("app_title").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.e(TAG, "App title updated");
String appTitle = dataSnapshot.getValue(String.class);
// update toolbar title
getSupportActionBar().setTitle(appTitle);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.e(TAG, "Failed to read app title value.", error.toException());
}
});
// Save / update the user
btnSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String name = inputName.getText().toString();
final String email = inputEmail.getText().toString();
// Check for already existed userId
if (TextUtils.isEmpty(userId)) {
createUser(name, email);
} else {
updateUser(name, email);
}
mFirebaseDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Your Logic here
for (DataSnapshot eventSnapshot : dataSnapshot.getChildren()) {
User mModel = eventSnapshot.getValue(User.class);
// Log.e("DATA" ,""+ mModel.getName());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
toggleButton();
}
// Changing button text
private void toggleButton() {
if (TextUtils.isEmpty(userId)) {
btnSave.setText("Save");
} else {
btnSave.setText("Update");
}
}
private void filter()
{
}
/**
* Creating new user node under 'users'
*/
private void createUser(String name, String email) {
// TODO
// In real apps this userId should be fetched
// by implementing firebase auth
if (TextUtils.isEmpty(userId)) {
userId = mFirebaseDatabase.push().getKey();
}
User user = new User(name, email);
mFirebaseDatabase.child(userId).setValue(user);
addUserChangeListener();
}
/**
* User data change listener
*/
private void addUserChangeListener() {
// User data change listener
mFirebaseDatabase.child(userId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if(!dataSnapshot.child("users").child("email").exists())
{
Log.e(TAG, "User not exists");
}
else
{
Log.e(TAG, "User exists");
}
// Check for null
if (user == null) {
Log.e(TAG, "User data is null!");
return;
}
Log.e(TAG, "User data is changed!" + user.name + ", " + user.email);
// Display newly updated name and email
txtDetails.setText(user.name + ", " + user.email);
// clear edit text
inputEmail.setText("");
inputName.setText("");
toggleButton();
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.e(TAG, "Failed to read user", error.toException());
}
});
}
private void updateUser(String name, String email) {
// updating the user via child nodes
if (!TextUtils.isEmpty(name))
mFirebaseDatabase.child(userId).child("name").setValue(name);
if (!TextUtils.isEmpty(email))
mFirebaseDatabase.child(userId).child("email").setValue(email);
}
}
Inside ValueEventListener() check email address is exist or not
Try this
if(!dataSnapshot.child("users").child("email").exist)
then insert new value
If you are trying to create a rule for block user have 2 accounts with same email, you can use the rules inside firebase. There are rules ready for this.
Authentication -> Method -> botton functions.
Related
I am using Firebase Authentication in my app where the users can register using Email & Password and he has to verify the email.
The user gets the verification mails, but when he verifies it and comes back to the app, the isEmailVerified() is always false. So my app still doesn't allow the user to use all functions in spite of the fact that he has verified his email.
But if they log out and login again, the isEmailVerified() returns true immediately. But is it not good to log out the user and login back again.
public class Profile extends AppCompatActivity {
FirebaseDatabase database;
DatabaseReference myRef;
TextView name;
Button logout;
FirebaseAuth auth;
String userStatus;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
auth = FirebaseAuth.getInstance();
database = FirebaseDatabase.getInstance();
myRef = database.getReference("name");
name=findViewById(R.id.id_name);
logout=findViewById(R.id.id_logout);
logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
auth.signOut();
startActivity(new Intent(Profile.this, Login.class));
}
});
userStatus= String.valueOf(auth.getCurrentUser().isEmailVerified());
if (userStatus =="true")
{
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
name.setText("Hello my name is: "+value);
Log.d("ashu", "Value is: " + value);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.d("ashu", "Failed to read value.", error.toException());
}
});
}
else {
Toast.makeText(Profile.this,"Verify your email ", Toast.LENGTH_SHORT).show();
name.setText("Verify your email");
}}}
Here is my answer after putting some logic
userStatus = String.valueOf(auth.getCurrentUser().isEmailVerified());
// user has not verified the email
Toast.makeText(Profile.this,"Verify your email ", Toast.LENGTH_SHORT).show();
name.setText("Verify your email");
auth.getCurrentUser().reload().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (userStatus =="true")
{
//if they have verified the email
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// retrieving the value of current user
String value = dataSnapshot.getValue(String.class);
name.setText("Hello my name is: "+value);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.d("ashu", "Failed to read value.", error.toException());
}
});
}
else {
name.setText("Verify your mail");
}
}
});
}
Hi I am making an app where you enter a number in an EditText, if that number matches with some key from the database in Firebase it will show up the value of that key in a TextView.
Here's the structure of the database:
Structure DB
The problem i have is that when i enter "1" in my EditText and it searches for the key that matches with it in the database i can retrieve the value of it because it's the first child (i guess) but when i enter another key (2-5) it says that doesn't exists because of the else sentence in my code.
I think i'm not iterating the full database so i can retrieve the correct value.
Here's the code:
public class MainActivity extends AppCompatActivity {
private DatabaseReference mDatabase;
private TextView mEstado ;
private Button B_buscar;
private EditText E_buscar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDatabase = FirebaseDatabase.getInstance().getReference().child("no_orden");
mEstado = (TextView) findViewById(R.id.estado);
B_buscar = (Button) findViewById(R.id.B_buscar);
E_buscar = (EditText) findViewById(R.id.E_buscar);
B_buscar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String buscar = E_buscar.getText().toString().trim();
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DataSnapshot estado = dataSnapshot.getChildren().iterator().next();
if (estado.getKey().toString().equals(buscar)){
mEstado.setText("The number #" + buscar + " contains: " + estado);
}else{
if (buscar.equals("")){
mEstado.setText("Enter a valid number.");
}else {
mEstado.setText("The number #" + buscar + " doesn't exists.");
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}}
Hope someone can help me.
Thanks.
You can use a for iterator like this:
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
Log.d(TAG, "Key: "+postSnapshot.getKey());
Log.d(TAG, "Value: "+postSnapshot.getValue());
}
So you are trying to send a string called buscar and you want to check its existance, I suggest you do this :
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//in this part of your code use this
if(dataSnapshot.hasChild(buscar)){
//this means the number is found in the database
}else{
//this means the number is not found in the database
}
}
I want to implement sign up with two activities with the help of firebase, first sign up activity contains email mobile and password, and in this activity i want to check whether the entered email ID or mobile is registered or not, if it does not then move the data(i.e. email, mobile no. and password) to next activity where final registration will happen. The two methods which are present in the code i.e. userMobileExists() and userEmailExists() to check the email and mobile. But the problem is these are asynchronous so when I go to next activity then the Toast appear that email is already registered.
I am returning valid, if all the valid are true then it goes to next activity , I debugged it and it returns valid before going inside the method. It is because of asynchronous code, Please suggest something how it can be achieved on the first activity only. Or tell if I should provide the whole code.
public class SignupActivity extends AppCompatActivity {
private static final String TAG = "SignupActivity";
private static final int REQUEST_SIGNUP = 0;
private Firebase mRef = new Firebase("https://abcdef.firebaseio.com/");
private User user;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private ProgressDialog mProgressDialog;
boolean valid = true;
String email;
String mobile;
String password;
#Bind(R.id.input_email)
EditText _emailText;
#Bind(R.id.input_mobile)
EditText _mobileText;
#Bind(R.id.input_password)
EditText _passwordText;
#Bind(R.id.btn_next)
Button _signupButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup);
ButterKnife.bind(this);
//For Full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
mAuth = FirebaseAuth.getInstance();
//Back button initialization
Button backButton = (Button) findViewById(R.id.back_signup);
backButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent in = new Intent(view.getContext(), LoginActivity.class);
startActivity(in);
}
});
mAuth = FirebaseAuth.getInstance();
// mRef = Firebase(Config.FIREBASE_URL);
_signupButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signup();
}
});
}
protected void setUpUser() {
user.setPhoneNumber(_mobileText.getText().toString());
user.setEmail(_emailText.getText().toString());
user.setPassword(_passwordText.getText().toString());
}
//private void
public void signup() {
Log.d(TAG, "Signup");
//showProgressDialog();
if (validate() && userEmailExist() && userMobileExist()) {
onSignupSuccess();
} else {
onSignupFailed();
return;
}
//_signupButton.setEnabled(false);
email = _emailText.getText().toString();
mobile = _mobileText.getText().toString();
password = _passwordText.getText().toString();
// TODO: Implement your own signup logic here.
}
public void onSignupSuccess() {
//_signupButton.setEnabled(true);
Log.d(TAG, "NEXT BUTTTON");
//hideProgressDialog();
Intent in = new Intent(this, SignupActivity2.class);
in.putExtra("Email", _emailText.getText().toString());
in.putExtra("Mobile", _mobileText.getText().toString());
startActivity(in);
/*setResult(RESULT_OK, null);
finish();*/
}
public void onSignupFailed() {
// hideProgressDialog();
Toast.makeText(getBaseContext(), "SignUp failed", Toast.LENGTH_LONG).show();
// _signupButton.setEnabled(true);
}
public boolean validate() {
email = _emailText.getText().toString();
mobile = _mobileText.getText().toString();
password = _passwordText.getText().toString();
if (email.isEmpty() || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
_emailText.setError("enter a valid email address");
valid = false;
} else {
_emailText.setError(null);
}
if (mobile.isEmpty() || mobile.length() != 10) {
_mobileText.setError("Enter Valid Mobile Number");
valid = false;
} else {
_mobileText.setError(null);
}
if (password.isEmpty() || password.length() < 4 || password.length() > 10) {
_passwordText.setError("between 4 and 10 alphanumeric characters");
valid = false;
} else {
_passwordText.setError(null);
}
return valid;
}
public boolean userEmailExist() {
//private Firebase mRef = new Firebase("https://.firebaseio.com/users/");
mRef.child("users").orderByChild("email").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue()== _emailText.getText().toString()) {
Toast.makeText(getBaseContext(), "Email already exist. Please choose a different one", Toast.LENGTH_SHORT).show();
_emailText.setError("Email already exist. Please choose a different one");
valid = false;
} else {
email = _emailText.getText().toString();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
return valid;
}
public boolean userMobileExist() {
mRef.child("users").
orderByChild("cellPhone").equalTo(_mobileText.getText().toString()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
_mobileText.setError("Mobile Number already exist");
valid = false;
} else {
mobile = _mobileText.getText().toString();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
return valid;
}
#Override
public void onBackPressed() {
// Disable going back to the MainActivity
moveTaskToBack(true);
}
public void showProgressDialog(){
if(mProgressDialog == null){
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("loading");
mProgressDialog.setIndeterminate(true);
}
mProgressDialog.show();
}
public void hideProgressDialog(){
if(mProgressDialog != null && mProgressDialog.isShowing()){
mProgressDialog.dismiss();
}
}
}
You need to grasp the concept of callbacks. You cannot return a variable that's assigned asynchronously.
As a quick solution to your problem, start with an interface
public interface OnUserActionListener {
void onExists(Boolean exists);
}
Then, make your methods be void and accept a parameter
public void userEmailExist(final String email, final OnUserActionListener listener) {
mRef.child("users")
.orderByChild("email")
.equalTo(email)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
listener.onExists( dataSnapshot.exists() );
}
...
// no return statement
}
Then, when you call that method, you can pass in the string value you want to search for, and implement your interface.
So replace this synchronous code
validate() && userEmailExist()
With the async version
if (validate()) { // This is synchonous
final String email = _emailText.getText().toString();
final String mobile = _mobileText.getText().toString();
// This is asynchronous
userEmailExist(email, new OnUserActionListener() {
#Override
public void onExists(Boolean exists) {
if (exists) {
Toast.makeText(getBaseContext(), "Email already exist. Please choose a different one", Toast.LENGTH_SHORT).show();
_emailText.setError("Email already exist. Please choose a different one");
onSignupFailed();
} else {
onSignupSuccess();
}
}
});
However you choose to define that interface is up to you
And again, worth repeating, don't assign a field valid within your callbacks. Try your best to implement all logic requiring a value to the callback itself
You can also implement the entire interface on the class, which is what I would recommend in this scenario as a SignUpActivity because you want to listen for user event actions such as success or error
Just an example using the method names you already have
public interface OnUserActionListener {
// Combine the email and phone into one action
void onUserExists(User user, Boolean exists);
void onSignupSuccess(User user);
void onSignupFailed(String reason);
}
public class SignupActivity extends AppCompatActivity
implements OnUserActionListner { // Implement this interface
// Define the needed methods
#Override
public void onUserExists(User user, Boolean exists) {
if (exists) {
onSignupFailed("User " + user + " already exists");
} else {
onSignupSuccess(user);
}
}
#Override
public void onSignupSuccess(User user) {
// Do something
}
#Override
public void onSignupFailed(String reason) {
Toast.makeText(this, reason, Toast.LENGTH_SHORT).show();
}
#Override
protected void onCreate(Bundle b) {
...
}
etc. etc.
Then, that other method call simply becomes.
if (validate()) { // This is synchonous
final String email = _emailText.getText().toString();
final String mobile = _mobileText.getText().toString();
// This is asynchronous & you defined the Activity as the interface
userEmailExist(email, SignupActivity.this);
I'm not satisfied with the accepted answer because when I used it in my project it still failed. After trying many thing I write my own code ... and it is working. If you want check whether user is already registered or not you can try the following code.
private void isUserAlreadySignUp(String phone){
firebaseAuth = FirebaseAuth.getInstance();
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("authUser");
// after getting reference of child, checked orderbykey so we get if phone is key we can get ref in dataSnapshot...
databaseReference.child( "userPhone" ).orderByKey().equalTo( phone ).addListenerForSingleValueEvent( new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Boolean isExists = dataSnapshot.exists();
if (isExists)
showToast( "This number is alredy Registerd..!!" );
else
{
// if mobile is not registered you can go ahead...
// You can write your further code here or call methods...
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
showToast("Error :" + databaseError);
wSignUpProgressBar.setVisibility( View.GONE );
}
} );
}
// For Toast msg...
private void showToast(String s){ Toast.makeText( getActivity(), s , Toast.LENGTH_SHORT ).show(); }
To register a users mobile number on the database after authenticating the user, you can call this method.
// Register User on the database --------------------------
private void registerUserOnDatabase( String userPhone){
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference userRef = database.getReference("authUser").child("userPhone");
userRef.child( userPhone ).setValue( userPhone );
}
I am implementing an application using FireBase, in this application I have to save user information with user enter unique id. How can I do that. Actually it saving the data with random generated value. But I want to add a user enter unique id.
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
txtDetails = (TextView) findViewById(R.id.txt_user);
inputName = (EditText) findViewById(R.id.name);
inputEmail = (EditText) findViewById(R.id.email);
btnSave = (Button) findViewById(R.id.btn_save);
mFirebaseInstance = FirebaseDatabase.getInstance();
// get reference to 'users' node
mFirebaseDatabase = mFirebaseInstance.getReference("users");
// store app title to 'app_title' node
mFirebaseInstance.getReference("app_title").setValue("Realtime Database");
// app_title change listener
mFirebaseInstance.getReference("app_title").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.e(TAG, "App title updated");
// update toolbar title
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.e(TAG, "Failed to read app title value.", error.toException());
}
});
// Save / update the user
btnSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String name = inputName.getText().toString();
String email = inputEmail.getText().toString();
// Check for already existed userId
if (TextUtils.isEmpty(userId)) {
createUser(name, email);
} else {
createUser(name, email);
}
}
});
toggleButton();
}
// Changing button text
private void toggleButton() {
if (TextUtils.isEmpty(userId)) {
btnSave.setText("Save");
} else {
btnSave.setText("Save");
}
}
/**
* Creating new user node under 'users'
*/
private void createUser(String name, String email) {
// TODO
// In real apps this userId should be fetched
// by implementing firebase auth
if (TextUtils.isEmpty(userId)) {
userId = mFirebaseDatabase.push().getKey();
}
User user = new User(name, email);
mFirebaseDatabase.child(userId).push().setValue(user);
addUserChangeListener();
}
/**
* User data change listener
*/
private void addUserChangeListener() {
// User data change listener
mFirebaseDatabase.child(userId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
// Check for null
if (user == null) {
Log.e(TAG, "User data is null!");
return;
}
Log.e(TAG, "User data is changed!" + user.name + ", " + user.email);
// Display newly updated name and email
// txtDetails.setText(user.name + ", " + user.email);
// clear edit text
inputEmail.setText("");
inputName.setText("");
toggleButton();
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.e(TAG, "Failed to read user", error.toException());
}
});
}
private void updateUser(String name, String email) {
// updating the user via child nodes
if (!TextUtils.isEmpty(name))
mFirebaseDatabase.child(userId).child("name").setValue(name);
if (!TextUtils.isEmpty(email))
mFirebaseDatabase.child(userId).child("email").setValue(email);
}
To save user data under an unique identifier i suggest you using the email address in stead of pushing a new key or using the uid. The email address is unique and easy to use. But because Firebase does not accept . symbol in the key i suggest you encode the email address like this:
name#email.com -> name#email,com
As you see, i have changed the the dot symbol . with a coma ,. To achive this i recomand you using this methods:
static String encodeUserEmail(String userEmail) {
return userEmail.replace(".", ",");
}
static String decodeUserEmail(String userEmail) {
return userEmail.replace(",", ".");
}
Hope it helps.
i am making a simple blog app using firebase as backend. in app i am showing comments list in post detail activity i want to implement edit and delete button in the front of every comment and want to visible it only if that comment write by the current user
this is my postDetailActivity
where should i need to implement the delete button
plz... help me if u need any other info comment....
updated to FirbaseRecyclerView but now delete button not working
public class PostDetailActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "PostDetailActivity";
public static final String EXTRA_POST_KEY = "post_key";
private DatabaseReference mPostReference;
private DatabaseReference mCommentsReference;
private ValueEventListener mPostListener;
protected String mPostKey;
private FirebaseRecyclerAdapter<Comment, CommentViewHolder> mAdapter;
private ImageView postPic;
private TextView mTitleView;
private TextView mBodyView;
private EditText mCommentField;
private Button mCommentButton;
public Button del_comment;
private RecyclerView mCommentsRecycler;
private LinearLayoutManager mlinearLayoutManager;
private String commentKey;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_detail);
// Get post key from intent
mPostKey = getIntent().getStringExtra(EXTRA_POST_KEY);
if (mPostKey == null) {
throw new IllegalArgumentException("Must pass EXTRA_POST_KEY");
}
// Initialize Database
mPostReference = FirebaseDatabase.getInstance().getReference()
.child("posts").child(mPostKey);
mCommentsReference = FirebaseDatabase.getInstance().getReference()
.child("post-comments");
// Initialize Views
// mAuthorView = (TextView) findViewById(R.id.post_author);
mTitleView = (TextView) findViewById(R.id.post_title);
mBodyView = (TextView) findViewById(R.id.post_body);
postPic = (ImageView) findViewById(R.id.form_details_image);
mCommentField = (EditText) findViewById(R.id.field_comment_text);
mCommentButton = (Button) findViewById(R.id.button_post_comment);
del_comment = (Button) findViewById(R.id.remove_comment);
mCommentsRecycler = (RecyclerView) findViewById(R.id.recycler_comments);
mCommentButton.setOnClickListener(this);
mCommentsRecycler.setHasFixedSize(true);
mlinearLayoutManager = new LinearLayoutManager(this);
mCommentsRecycler.setLayoutManager(mlinearLayoutManager);
}
private Query getcommentQuery(DatabaseReference mCommentsReference) {
return mCommentsReference.child(mPostKey);
}
#Override
public void onStart() {
super.onStart();
// Add value event listener to the post
// [START post_value_event_listener]
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
Post post = dataSnapshot.getValue(Post.class);
// [START_EXCLUDE]
// mAuthorView.setText(post.author);
mTitleView.setText(post.title);
mBodyView.setText(post.body);
final String formImage = String.valueOf(post.postDetailPic);
// [END_EXCLUDE]
if (formImage.length() > 0) {
Picasso.with(getApplicationContext()).load(formImage)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(postPic, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
//Try again online if cache failed
Picasso.with(getApplicationContext())
.load(formImage)
//.error(R.drawable.ic_warning_black_24dp)
.into(postPic, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Log.v("Picasso","Could not fetch image");
}
});
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
// [START_EXCLUDE]
Toast.makeText(PostDetailActivity.this, "Failed to load post.",
Toast.LENGTH_SHORT).show();
// [END_EXCLUDE]
}
};
mPostReference.addValueEventListener(postListener);
// [END post_value_event_listener]
// Keep copy of post listener so we can remove it when app stops
mPostListener = postListener;
// Listen for comments
Query commentQuery = getcommentQuery(mCommentsReference);
mAdapter = new FirebaseRecyclerAdapter<Comment, CommentViewHolder>(Comment.class,R.layout.item_comment,
CommentViewHolder.class, commentQuery) {
#Override
protected void populateViewHolder(final CommentViewHolder viewHolder,final Comment model,final int position) {
final DatabaseReference commentRef = getRef(position);
commentKey = commentRef.getKey();
if (model.commenter_id.containsKey(gUid())){
viewHolder.rm_comment.setVisibility(View.VISIBLE);
}
viewHolder.bindToPost(model, new View.OnClickListener() {
#Override
public void onClick(View view) {
mCommentsReference.child(mPostKey).child(commentKey).removeValue();
}
});
}
};
mCommentsRecycler.setAdapter(mAdapter);
}
#Override
public void onStop() {
super.onStop();
// Remove post value event listener
if (mPostListener != null) {
mPostReference.removeEventListener(mPostListener);
}
// Clean up comments listener
mAdapter.cleanup();
}
#Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.button_post_comment) {
postComment();
}
}
private void postComment() {
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
assert mUser != null;
final String uid = mUser.getUid();
final DatabaseReference commentDb = FirebaseDatabase.getInstance().getReference().child("Users").child(uid);
commentDb.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user information
User user = dataSnapshot.getValue(User.class);
String authorName = user.name;
String commentUserPic = user.ProfilePic;
// Create new comment object
String commentText = mCommentField.getText().toString();
HashMap<String, Object> dateCreated;
{
//Otherwise make a new object set to ServerValue.TIMESTAMP
dateCreated = new HashMap<String, Object>();
dateCreated.put("timeStamp", ServerValue.TIMESTAMP);
}
HashMap<String,Boolean> commenter_id ;
{
commenter_id = new HashMap<String, Boolean>();
commenter_id.put(getUid(),true);
}
Comment comment = new Comment(uid, authorName, commentText, commentUserPic, dateCreated, commenter_id);
// Push the comment, it will appear in the list
mCommentsReference.push().setValue(comment);
// Clear the field
mCommentField.setText(null);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
private Context mContext;
private DatabaseReference mDatabaseReference;
private ChildEventListener mChildEventListener;
private List<String> mCommentIds = new ArrayList<>();
private List<Comment> mComments = new ArrayList<>();
private String mkey;
// mContext = context;
// mDatabaseReference = ref;
// Create child event listener
// [START child_event_listener_recycler]
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
taskDeletion(dataSnapshot);
// A new comment has been added, add it to the displayed list
Comment comment = dataSnapshot.getValue(Comment.class);
mkey = dataSnapshot.getKey();
// [START_EXCLUDE]
// Update RecyclerView
mCommentIds.add(dataSnapshot.getKey());
mComments.add(comment);
mAdapter.notifyItemInserted(mComments.size() - 1);
// [END_EXCLUDE]
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
Comment newComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int commentIndex = mCommentIds.indexOf(commentKey);
if (commentIndex > -1) {
// Replace with the new data
mComments.set(commentIndex, newComment);
// Update the RecyclerView
mAdapter.notifyItemChanged(commentIndex);
} else {
Log.w(TAG, "onChildChanged:unknown_child:" + commentKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so remove it.
String commentKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int commentIndex = mCommentIds.indexOf(commentKey);
if (commentIndex > -1) {
// Remove data from the list
mCommentIds.remove(commentIndex);
mComments.remove(commentIndex);
// Update the RecyclerView
mAdapter.notifyItemRemoved(commentIndex);
} else {
Log.w(TAG, "onChildRemoved:unknown_child:" + commentKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
// A comment has changed position, use the key to determine if we are
// displaying this comment and if so move it.
Comment movedComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
// ...
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("PostDetailActivity", "postComments:onCancelled", databaseError.toException());
Toast.makeText(mContext, "Failed to load comments.",
Toast.LENGTH_SHORT).show();
}
};
// ref.addChildEventListener(childEventListener);
// [END child_event_listener_recycler]
// Store reference to listener so it can be removed on app stop
// mChildEventListener = childEventListener;
private String gUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}