I am trying to verify if a username already exists in the Firebase DB and created a method to verify it.
The method should return true if the username is available and return false if the username is already taken.
public boolean isUsernameValid(final String newUsername, String oldUsername){
if(newUsername.equals(oldUsername)){
//if username is not changed
return true;
}else {
userValid = true;
databaseReference.orderByChild("Username").equalTo(newUsername).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long userCount = dataSnapshot.getChildrenCount();
if(userCount!=0){
userValid = false;
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return userValid; //username is valid if this returns true
}
}
this method is returning UserValid boolean first and then it is querying the database. Please let me know if I missed something.
This is returning true first, and then searching the DB for username and hence, it is always Overwriting the username in the DB.
This method is called from here:
if(!TextUtils.isEmpty(str_firstName)
&& !TextUtils.isEmpty(str_lastName)
&& !TextUtils.isEmpty(str_username)
&& verify.isEmailValid(str_email)
&& verify.isMobileNoValid(str_mobile)
//here
&& verify.isUserNameValid(str_username, globalSharedPrefs.getUserDetail("username").toString())){
progressDialog.setMessage("Saving Profile ...");
progressDialog.show();
//saving the photo
if(isImageClicked) {
filepath = storageReference.child("profile_photos").child(globalSharedPrefs.getUserDetail("uid").toString());
filepath.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//TODO: add picture remote/edit button in the XML
isImageClicked = false;
downloadUri = taskSnapshot.getDownloadUrl();
databaseReference.child("Profile Picture").setValue(downloadUri.toString());
uploadUserInfo();
Toast.makeText(UserProfileActivity.this, "Profile Saved.!", Toast.LENGTH_LONG)
.show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
updateProfileUI();
clickEditProfileButton(false);
Toast.makeText(UserProfileActivity.this, "Update Failed.!", Toast.LENGTH_LONG)
.show();
}
});
}
Database Structure
{
"userinfo" : {
"J6Y4Dtxe7Nh45B653U5AVXHFrSJ2" : {
"AccountId" : "",
"DOB" : "21 Jun, 2017",
"First Name" : "Krishna",
"Last Name" : "kk",
"Mobile" : "",
"Username" : "kittuov",
"uid" : "J6Y4Dtxe7Nh45B653U5AVXHFrSJ2"
},
"ck8x94FeHtUbC9DgHCkxmQt93Ar1" : {
"AccountId" : "",
"DOB" : "7 Dec, 1992",
"First Name" : "Seshagiri Rao",
"Last Name" : "Kornepati",
"Mobile" : "",
"Username" : "seshu1",
"uid" : "ck8x94FeHtUbC9DgHCkxmQt93Ar1"
},
"iDBn0lYIZFSgll9KyVje0T6JFIy2" : {
"AccountId" : "",
"DOB" : "",
"First Name" : "Ramesh",
"Last Name" : "Devarapu",
"Mobile" : "",
"Username" : "rameshb",
"uid" : "iDBn0lYIZFSgll9KyVje0T6JFIy2"
}
}
Try this
if(str_username.equals(globalSharedPrefs.getUserDetail("username").toString()))){
sumbit();
}else {
databaseReference.orderByChild("Username").equalTo(newUsername).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long userCount = dataSnapshot.getChildrenCount();
if(userCount==0){
sumbit();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
private void sumbit(){
if(!TextUtils.isEmpty(str_firstName)
&& !TextUtils.isEmpty(str_lastName)
&& !TextUtils.isEmpty(str_username)
&& verify.isEmailValid(str_email)
&& verify.isMobileNoValid(str_mobile)
){
progressDialog.setMessage("Saving Profile ...");
progressDialog.show();
//saving the photo
if(isImageClicked) {
filepath = storageReference.child("profile_photos").child(globalSharedPrefs.getUserDetail("uid").toString());
filepath.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//TODO: add picture remote/edit button in the XML
isImageClicked = false;
downloadUri = taskSnapshot.getDownloadUrl();
databaseReference.child("Profile Picture").setValue(downloadUri.toString());
uploadUserInfo();
Toast.makeText(UserProfileActivity.this, "Profile Saved.!", Toast.LENGTH_LONG)
.show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
updateProfileUI();
clickEditProfileButton(false);
Toast.makeText(UserProfileActivity.this, "Update Failed.!", Toast.LENGTH_LONG)
.show();
}
});
}
}
Related
Here is my data structure.
"Posts" : {
"-MpVVpVIqmn0Iu78hDRp" : {
"description" : "",
"picture" : "",
"postKey" : "",
"reports" : 0,
"timeStamp" : 1638001760487,
"title" : "",
"userId" : "",
"userPhoto" : ""
},
"-MpVcioadtvRBRaa0n96" : {
"description" : "",
"picture" : "",
"postKey" : "",
"reports" : 0,
"timeStamp" : 1638003830234,
"title" : "",
"userId" : "",
"userPhoto" : ""
},
I want to access the "reports" part. So I use
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("Posts").child("reports").setValue(1);
But It creates reports value 1 right below Posts not below "-MpVVpVIqmn0Iu78hDRp" this.
I want to increment the report. But I don't know how can I approach to reports node.
Here is my full code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_detail);
imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
et = (EditText)findViewById(R.id.post_detail_comment);
// let's set the statue bar to transparent
// ini Views
RvComment = findViewById(R.id.rv_comment);
imgPost =findViewById(R.id.post_detail_img);
imgUserPost = findViewById(R.id.post_detail_user_img);
imgCurrentUser = findViewById(R.id.post_detail_currentuser_img);
txtPostTitle = findViewById(R.id.post_detail_title);
txtPostDesc = findViewById(R.id.post_detail_desc);
txtPostDateName = findViewById(R.id.post_detail_date_name);
editTextComment = findViewById(R.id.post_detail_comment);
btnAddComment = findViewById(R.id.post_detail_add_comment_btn);
btnDeletePost = findViewById(R.id.button_delete);
btnnoti = findViewById(R.id.button_noti);
btncommentnoti = findViewById(R.id.comment_noti);
firebaseAuth = FirebaseAuth.getInstance();
firebaseUser = firebaseAuth.getCurrentUser();
firebaseDatabase = FirebaseDatabase.getInstance();
// add post delete button
mDatabase= FirebaseDatabase.getInstance().getReference();
myUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
//게시글 신고기능
btnnoti.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("Posts").child("reports").setValue(1);
}
});
btnDeletePost.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//여기 수정 주의 UId.equals(myUid)
if (true){
Toast.makeText(PostDetailActivity.this,"삭제중...",Toast.LENGTH_SHORT).show();
beginDelete();
onBackPressed();
}
}
});
// add Comment button click listener
btnAddComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
btnAddComment.setVisibility(View.INVISIBLE);
DatabaseReference commentReference = firebaseDatabase.getReference(COMMENT_KEY).child(PostKey).push();
String comment_content = editTextComment.getText().toString();
String uid = firebaseUser.getUid();
String uname = firebaseUser.getDisplayName();
if (firebaseUser.getPhotoUrl()!=null){
String uimg = firebaseUser.getPhotoUrl().toString();
Comment comment = new Comment(comment_content,uid,uimg,uname);
commentReference.setValue(comment).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
showMessage("댓글이 등록되었습니다.");
editTextComment.setText("");
btnAddComment.setVisibility(View.VISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
showMessage("fail to add comment : "+e.getMessage());
}
});
}
else{
String usphoto =Integer.toString(R.drawable.userphoto);
Comment comment = new Comment(comment_content,uid,usphoto,uname);
commentReference.setValue(comment).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
showMessage("comment added");
editTextComment.setText("");
btnAddComment.setVisibility(View.VISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
showMessage("fail to add comment : "+e.getMessage());
}
});
}
}
});
// now we need to bind all data into those views
// first we need to get post data
// we need to send post detail data to this activity first ...
// now we can get post data
// 게시글 사진 백지 케이스
postImage = getIntent().getExtras().getString("postImage") ;
if(postImage!=null){
Glide.with(this).load(postImage).into(imgPost);
}
else{
Glide.with(this).load(R.drawable.whitepaper).into(imgPost);
}
String postTitle = getIntent().getExtras().getString("title");
txtPostTitle.setText(postTitle);
String userpostImage = getIntent().getExtras().getString("userPhoto");
if (userpostImage!=null){
Glide.with(this).load(userpostImage).into(imgUserPost);
}
else {
Glide.with(this).load(R.drawable.userphoto).into(imgUserPost);
}
String postDescription = getIntent().getExtras().getString("description");
txtPostDesc.setText(postDescription);
// set comment user image
if (firebaseUser.getPhotoUrl()!=null){
Glide.with(this).load(firebaseUser.getPhotoUrl()).into(imgCurrentUser);
}
else{
Glide.with(this).load(R.drawable.userphoto).into(imgCurrentUser);
}
// get post key
PostKey = getIntent().getExtras().getString("postKey");
String date = timestampToString(getIntent().getExtras().getLong("postDate"));
txtPostDateName.setText(date);
// get post uid
UId = getIntent().getExtras().getString("userId");
// ini Recyclerview Comment
iniRvComment();
}
private void beginDelete() {
//서버 관리용 개발자 옵션
if (myUid.equals("k1kn0JF5idhrMzuw46GarEIBgPw2")) {
long tlong = System.currentTimeMillis(); long ttime;
ttime = tlong - 3*24*60*60*1000;
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
Query queryByTimestamp = db.child("Posts").orderByChild("timeStamp").endAt(ttime);
queryByTimestamp.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot ds : task.getResult().getChildren()) {
ds.getRef().removeValue();
Toast.makeText(PostDetailActivity.this,"게시글이 삭제되었습니다.",Toast.LENGTH_SHORT).show();
}
} else {
Log.d("TAG", task.getException().getMessage());
Toast.makeText(PostDetailActivity.this,"게시글이 삭제되지않았습니다.",Toast.LENGTH_SHORT).show();
}
}
});
}
else if (UId.equals(myUid)) {
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
Query queryByTimestamp = db.child("Posts").orderByChild("postKey").equalTo(PostKey);
queryByTimestamp.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot ds : task.getResult().getChildren()) {
ds.getRef().removeValue();
Toast.makeText(PostDetailActivity.this, "게시글이 삭제되었습니다.", Toast.LENGTH_SHORT).show();
}
} else {
Log.d("TAG", task.getException().getMessage());
Toast.makeText(PostDetailActivity.this, "게시글이 삭제되지않았습니다.", Toast.LENGTH_SHORT).show();
}
}
});
}
else{
Toast.makeText(PostDetailActivity.this,"다른 사용자의 게시글입니다.",Toast.LENGTH_SHORT).show();
}
}
public void linearOnClick(View v) {
imm.hideSoftInputFromWindow(et.getWindowToken(), 0);
}
private void iniRvComment() {
RvComment.setLayoutManager(new LinearLayoutManager(this));
DatabaseReference commentRef = firebaseDatabase.getReference(COMMENT_KEY).child(PostKey);
commentRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
listComment = new ArrayList<>();
for (DataSnapshot snap:dataSnapshot.getChildren()) {
Comment comment = snap.getValue(Comment.class);
listComment.add(comment) ;
}
commentAdapter = new CommentAdapter(getApplicationContext(),listComment);
RvComment.setAdapter(commentAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void showMessage(String message) {
Toast.makeText(this,message,Toast.LENGTH_LONG).show();
}
private String timestampToString(long time) {
Calendar calendar = Calendar.getInstance(Locale.ENGLISH);
calendar.setTimeInMillis(time);
String date = DateFormat.format("yyyy-MM-dd",calendar).toString();
return date;
}
}
This is the part of my question
btnnoti.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("Posts").child("reports").setValue(1);
}
});
I also tried orderbychild but I think it is not the right code.
This code:
rootRef.child("Posts").child("reports").setValue(1);
You're telling the database to set the value of /Posts/reports to 1, which is precisely what it then does.
If you want increment the current value of a node, you can use the atomic increment operation:
rootRef.child("Posts").child("reports").setValue(ServerValue.increment(1));
If you want to increment the reports property of a specific node under Posts, you will need to know the key of that node. For example:
rootRef.child("Posts/-MpVVpVIqmn0Iu78hDRp/reports").setValue(ServerValue.increment(1));
If you don't know the key of the node to increment, but do know some other value that uniquely (enough) identifies the node(s) to update, you can use a query to find the keys.
For example, to update all nodes with a specific postKey:
Query query = rootRef.child("Posts").orderByChild("postKey").equalTo("thePostKeyValue");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
postSnapshot.getReference().child("reports").setValue(ServerValue.increment(1));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
just coding my first app in android studio and doing some stuff with the firebase realtime database. Basically I'm trying to verify if a user has already created a username, and if not the app prompts the user to create one by re-directing them to the settings. This all works good, but the thing is that once the user has set their username and returns back to the main menu they're re-rerouted back to the settings page. I looked into it and the code keeps returning false when trying to get a snapshot of their username but I don't understand why? Thank you in advance!
Here's the code that I think isn't working in the main activity
#Override
protected void onStart() {
super.onStart();
if(currentUser == null){
sendUserToLoginActivity();
}else{
VerifyUserExistence();
}
}
private void VerifyUserExistence() {
String currentUserID = mAuth.getCurrentUser().getUid();
RootRef.child(currentUserID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Boolean Name = snapshot.child("NAME").exists();
if(Name){
Toast.makeText(MainActivity.this, "Welcome", Toast.LENGTH_SHORT).show();
}
else{
sendUserToSettingsActivity();
Toast.makeText(MainActivity.this, Name.toString(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError error) {
}
});
}
Here's the update settings code:
private void UpdateSettings() {
String setUserName = userName.getText().toString();
String setStatus = userStatus.getText().toString();
if(TextUtils.isEmpty(setUserName)){
Toast.makeText(this, "Please set your username", Toast.LENGTH_SHORT).show();
}
if(TextUtils.isEmpty(setStatus)){
Toast.makeText(this, "Please set your status", Toast.LENGTH_SHORT).show();
}
else{
HashMap<String, String> profileMap = new HashMap<>();
profileMap.put("uid",currentUserID);
profileMap.put("NAME",setUserName);
profileMap.put("STATUS",setStatus);
RootRef.child("Users").child(currentUserID).setValue(profileMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
SendUserToMainActivity();
Toast.makeText(SettingsActivity.this, "Profile updated successfully", Toast.LENGTH_SHORT).show();
}else{
String message = task.getException().toString();
Toast.makeText(SettingsActivity.this, "Error: " + message, Toast.LENGTH_SHORT).show();
}
}
});
}
}
Here's the stuff in the JSON file
{
"Users" : {
"B2tdbjK9QXUVOpmH8YZgrHdy7rB2" : {
"NAME" : "cvjjcfh",
"STATUS" : "xvjjjhzx",
"uid" : "B2tdbjK9QXUVOpmH8YZgrHdy7rB2"
},
"X685CimY11Q0HXW1haiHVIQByWW2" : {
"NAME" : "lolinio",
"STATUS" : "bsbsksk",
"uid" : "X685CimY11Q0HXW1haiHVIQByWW2"
}
}
}
BTW the part of the code that always returns false is
snapshot.child("NAME").exists();
This is the JSON text
{
"User" : {
"E10W6iRbAUOa5XbFnedUuepswsw2" : {
"email" : "jay#gmail,com",
"type" : "Admin"
},
"Od6G6kbPHrScLVYrqmovaFP0gw03" : {
"email" : "gloria#yahoo,com",
"type" : "User"
},
"jCiHZCIThdQi1LhVSonN6UNxRok2" : {
"email" : "clara#yahoo,com",
"type" : "User"
}
}
}
on if (login.getType().equals("Admin") && login.getType() != null)
or if there are any other errors please let me know
public class SignInActivity extends AppCompatActivity {
private EditText memail;
private EditText mpassword;
private Button mlogin;
private Button mregister;
private ProgressBar mpgbar;
private FirebaseAuth mAuth;
FirebaseDatabase database;
DatabaseReference users;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_in);
database = FirebaseDatabase.getInstance();
users = database.getReference("User");
mAuth = FirebaseAuth.getInstance();
memail = findViewById(R.id.emailtv);
mpassword = findViewById(R.id.passwordtv);
mlogin = findViewById(R.id.loginBtn);
mregister = findViewById(R.id.regBtn);
mpgbar = findViewById(R.id.progressBar);
mregister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(SignInActivity.this, RegisterActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
return;
}
});
mlogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LoginUser(memail.getText().toString(), mpassword.getText().toString());
}
});
}
private void inProgress(boolean x) {
if (x) {
mpgbar.setVisibility(View.VISIBLE);
mlogin.setEnabled(false);
mregister.setEnabled(false);
} else {
mpgbar.setVisibility(View.GONE);
mlogin.setEnabled(true);
mregister.setEnabled(true);
}
}
private boolean isEmpty() {
if (TextUtils.isEmpty(memail.getText().toString())) {
memail.setError("REQUIRED");
return true;
}
if (TextUtils.isEmpty(mpassword.getText().toString())) {
mpassword.setError("REQUIRED");
return true;
}
return false;
}
private void LoginUser(final String email, final String pwd) {
if (isEmpty()) return;
inProgress(true);
users.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (!email.isEmpty()) {
User login = dataSnapshot.child(email).getValue(User.class);
if (login.getType().equals("Admin") && login.getType() != null) {
mAuth.signInWithEmailAndPassword(email.replace(",","."), pwd)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Toast.makeText(SignInActivity.this, "User signed in", Toast.LENGTH_LONG).show();
Intent intent = new Intent(SignInActivity.this, AdminPage.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
return;
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(SignInActivity.this, "Sign in failed" + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
} else if (login.getType().equals("User") && login.getType() != null) {
if (isEmpty()) return;
inProgress(true);
mAuth.signInWithEmailAndPassword(email.replace(",","."), pwd)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Toast.makeText(SignInActivity.this, "User signed in", Toast.LENGTH_LONG).show();
Intent intent = new Intent(SignInActivity.this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
return;
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(SignInActivity.this, "Sign in failed" + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
else
{
Toast.makeText(SignInActivity.this, "Sign in failed" , Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
It supposed to redirect user to home and admin to admin page. But it always crash.
You're loading the entire /User node, and then try to read a single User.class from it. That won't work, as /User contains multiple users. But you'll also first want to query the children under /User to only read users with the email address you're looking for.
Something like this:
private void LoginUser(final String email, final String pwd) {
Query query = users.orderByChild("email").equalTo(email)
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot userSnapshot: dataSnapshot.getChildren()) {
User login = userSnapshot.getValue(User.class);
...
}
}
}
});
}
The main differences:
Instead of loading all users, this queries the children under /User for the one(s) matching the email address.
Inside onDataChange there may be multiple matching child nodes, so we loop over those results.
Removed the child("email") inside the onDataChange, since that doesn't work if you're trying to read an entire User object.
I'm trying to download data for my chat from Firebase database(structure of data is bellow and It is recommended structure from official Firebase web).
"chats": {
"one": {
"lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
"timestamp": 1459361875666
},
"two": { ... }
},
"members": {
"one": {
"member1": "cxgF3EddyMWiYybXdMsYwu5YQsn1",
"member2": "jdxBDm5MXBdX4zfGoEp9hgHqscn2"
};
"two": {
"member1": "cxgF3EddyMWiYybXdMsYwu5YQsn1",
"member2": "yGpTEPDfChVmUeEkzvCCY6IjQnA2"
};
},
"messages": {
"one": {
"m1": {
"name": "cxgF3EddyMWiYybXdMsYwu5YQsn1",
"message": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
"m2": {
"name": "jdxBDm5MXBdX4zfGoEp9hgHqscn2",
"message": "Yes.",
"timestamp": 1459361875689
},
},
"two": { ... }
}
Now I'm trying just to check if I(as logged user) am involved in the conversation and download just the last message under chats/and particular chat number. Also I have to download a profile picture of another user that is involved in this chat and then add last message and this picture to PrefenceScreen.
Here is code:
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("members");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final ArrayList<String> arrayList = new ArrayList<>();
for (final DataSnapshot snapshot : dataSnapshot.getChildren()) {
GenericTypeIndicator<Map<String, Object>> m = new GenericTypeIndicator<Map<String, Object>>() {
};
Map<String, Object> map = snapshot.getValue(m);
if (map.get("member1").equals(myUID)) {
arrayList.add(snapshot.getKey());
arrayList.add(map.get("member2").toString());
} else if (map.get("member2").equals(myUID)) {
arrayList.add(snapshot.getKey());
arrayList.add(map.get("member1").toString());
}
}
mStorage = FirebaseStorage.getInstance().getReference();
for (int i=0, y=1; y<arrayList.size(); i+=2, y+=2) {
Log.i("Chat", arrayList.get(i));
StorageReference storageReference = mStorage.child("photos").child(arrayList.get(y));
try {
final File localFile = File.createTempFile("images", "jpg");
final int finalI = i;
StorageTask<FileDownloadTask.TaskSnapshot> taskSnapshotStorageTask = storageReference.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Bitmap bitmap = BitmapFactory.decodeFile(localFile.getAbsolutePath());
Resources res = getResources();
final RoundedBitmapDrawable dr =
RoundedBitmapDrawableFactory.create(res, Bitmap.createScaledBitmap(bitmap, 150, 150, false));
dr.setCornerRadius(500);
DatabaseReference myRef2 = database.getReference("chats").child(arrayList.get(finalI)).child("lastMessage");
myRef2.addValueEventListener(new ValueEventListener() {
#SuppressLint("SetTextI18n")
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String message = dataSnapshot.getValue(String.class);
Log.d("TAG", "Value is: " + message);
PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(getActivity());
Preference preference = new Preference(getActivity());
preference.setTitle(message);
preference.setKey("Hej celkom v pohode");
preference.setIcon(dr);
preference.setSelectable(true);
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(getActivity(), ScrollingActivity.class);
startActivity(intent);
return false;
}
});
screen.addPreference(preference);
setPreferenceScreen(screen);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("TAG", "Failed to read value.", error.toException());
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
}
});
} catch (IOException e ) {
}
}
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("TAG", "Failed to read value.", error.toException());
}
});
The code is almost doing what It should. The problem is that it all the time adds just one Prefence because the screen.addPreference(preference); and setPreferenceScreen(screen); methods are inside onDataChange. Is there a way how to use methods after files are downloaded?
And also I think this code is messy and there must by simplier way to download all the data. You would be very thankful if you can help me with this. Thanks.
I'm using firebase to create To-Do android application. I'm use recyclerview and cardview to populate data fro firebase. But some weird things happen when i watch on Android Monitor and see my debug log fires twice onChildChanged:
D/DiaryAdapter: onChildChanged:-KIafq035E-pc6uT3Ej7
D/DiaryAdapter: onChildChanged:-KIafq035E-pc6uT3Ej7
and caused item on recyclerview blink twice (blink efect on item when it's updated)
i put this on MainFragment.java onStart()
// Setup adapter
diaryAdapter = new DiaryAdapter(getContext(),mDiaryRef);
recyclerDiary.setAdapter(diaryAdapter);
On my adapter constructor
public DiaryAdapter(final Context context, DatabaseReference ref) {
mContex = context;
mDatabaseRefrence = ref;
mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
Diary diary = dataSnapshot.getValue(Diary.class);
mDiary.add(diary);
mDiaryID.add(dataSnapshot.getKey());
notifyItemInserted(mDiary.size() - 1);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
Diary newDiary = dataSnapshot.getValue(Diary.class);
int diaryIndex = mDiaryID.indexOf(dataSnapshot.getKey());
if (diaryIndex > -1) {
mDiary.set(diaryIndex, newDiary);
notifyItemChanged(diaryIndex);
} else {
Log.w(TAG, "onChildChanged:unknown_child:" + dataSnapshot.getKey());
}
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
int diaryIndex = mDiaryID.indexOf(dataSnapshot.getKey());
if (diaryIndex > -1) {
mDiary.remove(diaryIndex);
mDiaryID.remove(diaryIndex);
notifyItemRemoved(diaryIndex);
} else {
Log.w(TAG, "onChildRemoved:unknown_child:" + dataSnapshot.getKey());
}
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "postComments:onCancelled", databaseError.toException());
Toast.makeText(mContex, "Failed to load diary.",
Toast.LENGTH_SHORT).show();
}
};
ref.addChildEventListener(mChildEventListener);
}
I'm following from firebase android sample here
Edit: Database structure
{
"diary" : {
"2Y4XwraNoRdIFPBJY0XxwdPte0H2" : {
"1437" : {
"-KIahAPVU_WrmP5rDcAa" : {
"created" : 1464159484316,
"infaq" : {
"selesai" : false
},
"ngaji" : {
"ayatAkhir" : 0,
"ayatMulai" : 0,
"selesai" : true,
"surahAkhir" : 0,
"surahMulai" : 0
},
"puasa" : {
"sahur" : false,
"selesai" : true,
"summary" : ""
},
"sholat" : {
"ashar" : true,
"dhuhur" : true,
"done" : true,
"mIsya" : true,
"maghrib" : true,
"subuh" : true
},
"summary" : "Puasa kedua Tos",
"tanggal" : 2,
"tarawih" : {
"ringkasan" : "",
"selesai" : true
},
"updated" : 1464186194796
},
}
}
}