I am working on an android project where I am using firebase database.
The problem is that i want to check for a particular data which may exist after sometime in the database.
For a clarification, there are two users in firebase, 1) Prem, 2) Suraj. When Prem clicks on a button "Send requests" then Suraj gets Prem's request now if Suraj clicks on that request then the firebase data base makes a child "Playing" which contains - "Prem:Suraj" and now from Prem's side i want to check if Suraj has clicked on that request so i thought it would be best to see if that data exists but its not working because the data will be existing in future and not in the current time.
If anyone could help me, i'll be really grateful.
`//Sender Side
private void confirmRequestTo(final String OtherPlayer) {
AlertDialog.Builder b = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.connecting_players, null);
b.setView(dialogView);
b.setTitle("Start Game?");
b.setMessage("Connect with " + OtherPlayer );
b.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
myRef.child("Users").child(OtherPlayer).child("request").push().setValue(LoginUserID); //Sending the Request
Toast.makeText(Request_InterfaceActivity.this, "Waiting For " + OtherPlayer + " to Join", Toast.LENGTH_SHORT).show();
Request_InterfaceActivity.help = true;
//Waiting for the Request to be Accepted
String pid = UserName + ":" + OtherPlayer;
DatabaseReference playref = myRef.child("Playing");
int sum = 100;
for(int i =0; i<sum;i++) {
playref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (int j = 0; j < sum; j++) {
if (snapshot.hasChild(UserName + ":" + OtherPlayer)) {
StartGame(UserName + ":" + OtherPlayer, OtherPlayer, "TO");
} else {
Toast.makeText(Request_InterfaceActivity.this, UserName + ":" + OtherPlayer, Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.d(TAG, error.getMessage());
}
});
}
}
}).setNegativeButton("Back", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Request_InterfaceActivity.help = false;
}
});
b.show();
}
//Receiver Side
private void confirmRequestFrom(final String OtherPlayer) {
AlertDialog.Builder b = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.connecting_players, null);
b.setView(dialogView);
b.setTitle("Start Game?");
b.setMessage("Connect with " + OtherPlayer );
b.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
StartGame(OtherPlayer + ":" + UserName, OtherPlayer, "From");
}
});
b.setNegativeButton("Back", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
b.show();
}
private void StartGame(String PlayerGameID, String OtherPlayer, String requestType) {
//To Implement Later
myRef.child("Playing").child(PlayerGameID).removeValue();
Intent i = new Intent(getApplicationContext(),OnlineGameActivity.class);
i.putExtra("PlayerSession", PlayerGameID);
i.putExtra("Username", UserName);
i.putExtra("OtherPlayer", OtherPlayer);
i.putExtra("LoginUID", LoginUID);
i.putExtra("RequestType", requestType);
startActivity(i);
finish();
myRef.getRoot().child("Users").orderByKey().equalTo(UserName).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot postsnapshot :snapshot.getChildren()){
String key = myRef.child("Users").child(UserName).getKey();
myRef.child("Users").child(key).removeValue();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}`
Related
I am developing an e-commerce android application in which i have two sides(admin side and user side). I have implemented in-app messaging in my application where user can send message to admin and admin can send message to user. Now, i want to add notifications to this part that when a admin or user sends message the other side receives notification if it is in the app because i want to do this without server side code. I tried googling it but couldn't find any good solution. So can anyone help?
Here is my chat class for user:
chat_messages_view_panel = (LinearLayout)findViewById(R.id.chat_messages_view_panel);
chat_messages_scroll_view = (ScrollView)findViewById(R.id.chat_messages_scroll_view);
chatImagesRef = FirebaseStorage.getInstance().getReference().child("Chat Images");
FirebaseDatabase.getInstance().getReference().child("Admins").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot item : snapshot.getChildren()) {
admin = item.getValue(Admin.class);
break;
}
loadMessages();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
FirebaseDatabase.getInstance().getReference().child("Messages").child(Prevelent.onlineUser.getEmail()).
addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot)
{
for(DataSnapshot item: snapshot.getChildren())
{
Message message = item.getValue(Message.class);
if(!message_ids.contains(message.getId()))
{
message_ids.add(message.getId());
addMessage(message);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
sendButton = (ImageButton)findViewById(R.id.sendMessage);
messageContent = (EditText)findViewById(R.id.chat_message_box);
sendPictureButton = (ImageButton) findViewById(R.id.uploadImage);
loadingBar = new ProgressDialog(this);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(messageContent.getText().toString().equals("")){
return;
}
Calendar calendar = Calendar.getInstance();
SimpleDateFormat currentDate = new SimpleDateFormat("yyyy MM, dd");
String saveCurrentDate = currentDate.format(calendar.getTime());
SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm:ss:SSS a");
String saveCurrentTime = currentTime.format(calendar.getTime());
DatabaseReference messageRef = FirebaseDatabase.getInstance().getReference();
Map<String, Object> userdataMap = new HashMap<>();
userdataMap.put("id", Prevelent.onlineUser.getEmail() + " : " + saveCurrentDate + " " + saveCurrentTime);
userdataMap.put("content", messageContent.getText() + "");
userdataMap.put("sentByEmail", Prevelent.onlineUser.getEmail());
userdataMap.put("sentByName", Prevelent.onlineUser.getName());
userdataMap.put("sentToEmail", admin.getEmail());
userdataMap.put("sentToName", admin.getName());
userdataMap.put("sentAt", saveCurrentDate + " " + saveCurrentTime);
userdataMap.put("messageType", "text");
messageRef.child("Messages").child(Prevelent.onlineUser.getEmail()).child(saveCurrentDate + " " + saveCurrentTime).
updateChildren(userdataMap)
.addOnCompleteListener(new OnCompleteListener<Void>(){
#Override
public void onComplete(#NonNull Task<Void> task) {
messageContent.setText("");
}
});
}
});
sendPictureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
OpenGallery();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==GalleryPick && resultCode==RESULT_OK && data!=null)
{
ImageUri = data.getData();
AlertDialog.Builder alertadd = new AlertDialog.Builder(chatActivity.this);
LayoutInflater factory = LayoutInflater.from(chatActivity.this);
final View view = factory.inflate(R.layout.alertdialog_imageview_layout, null);
ImageView imageView = view.findViewById(R.id.dialog_imageview);
imageView.setImageURI(ImageUri);
alertadd.setView(view);
alertadd.setCancelable(false);
alertadd.setPositiveButton("Upload", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int sumthin) {
loadingBar.setTitle("Picture Upload");
loadingBar.setMessage("Please wait while your image is being uploaded");
loadingBar.setCanceledOnTouchOutside(false);
loadingBar.show();
UploadImage();
dlg.dismiss();
}
});
alertadd.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int sumthin) {
dlg.dismiss();
}
});
alertadd.show();
}
}
public void UploadImage(){
Calendar calendar = Calendar.getInstance();
SimpleDateFormat currentDate = new SimpleDateFormat("yyyy MM, dd");
saveCurrentDate = currentDate.format(calendar.getTime());
SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm:ss:SSS a");
saveCurrentTime = currentTime.format(calendar.getTime());
pictureRandomKey = saveCurrentDate + saveCurrentTime;
final StorageReference filePath = chatImagesRef.child(ImageUri.getLastPathSegment() + pictureRandomKey + ".jpg");
final UploadTask uploadTask = filePath.putFile(ImageUri);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e)
{
String message = e.toString();
Toast.makeText(chatActivity.this, "Error: " + message, Toast.LENGTH_SHORT).show();
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
{
loadingBar.cancel();
Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception
{
if (!task.isSuccessful())
{
throw task.getException();
}
downloadImageUrl = filePath.getDownloadUrl().toString();
return filePath.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task)
{
if (task.isSuccessful())
{
downloadImageUrl = task.getResult().toString();
DatabaseReference messageRef = FirebaseDatabase.getInstance().getReference();
Map<String, Object> userdataMap = new HashMap<>();
userdataMap.put("id", Prevelent.onlineUser.getEmail() + " : " + saveCurrentDate + " " + saveCurrentTime);
userdataMap.put("content", downloadImageUrl);
userdataMap.put("sentByEmail", Prevelent.onlineUser.getEmail());
userdataMap.put("sentByName", Prevelent.onlineUser.getName());
userdataMap.put("sentToEmail", admin.getEmail());
userdataMap.put("sentToName", admin.getName());
userdataMap.put("sentAt", saveCurrentDate + " " + saveCurrentTime);
userdataMap.put("messageType", "picture");
messageRef.child("Messages").child(Prevelent.onlineUser.getEmail()).child(saveCurrentDate + " " + saveCurrentTime).
updateChildren(userdataMap)
.addOnCompleteListener(new OnCompleteListener<Void>(){
#Override
public void onComplete(#NonNull Task<Void> task) {
messageContent.setText("");
}
});
}
}
});
}
});
}
private void addMessage(Message message)
{
if(message.getMessageType().equals("text")){
if(message.getSentByEmail().equals(Prevelent.onlineUser.getEmail()))
{
addMyMessage(message);
}
else
{
addTheirMessage(message);
}
}else{
int id = View.generateViewId();
imagesUrl.put(id, message.getContent());
if(message.getSentByEmail().equals(Prevelent.onlineUser.getEmail()))
{
addMyMessageImage(message, id);
}
else
{
addTheirMessageImage(message, id);
}
}
}
private void addTheirMessageImage(Message message, int id) {
try {
View v = LayoutInflater.from(chatActivity.this).inflate(R.layout.their_message_image, null);
TextView sender_name_view = v.findViewById(R.id.sender_name_view);
ImageView imageView = v.findViewById(R.id.receivedImageView);
TextView message_time = v.findViewById(R.id.received_message_box_time);
sender_name_view.setText(message.getSentByName());
Picasso.get().load(message.getContent()).into(imageView);
message_time.setText(getMomentAgo(message.getSentAt()));
imageView.setId(id);
chat_messages_view_panel.addView(v);
scrollChatToBottom();
}catch (Exception ignored)
{
}
}
private void addMyMessageImage(Message message, int id) {
try {
View v = LayoutInflater.from(chatActivity.this).inflate(R.layout.my_message_image, null);
ImageView imageView = v.findViewById(R.id.sentImageView);
TextView message_time = v.findViewById(R.id.sent_message_box_time);
Picasso.get().load(message.getContent()).into(imageView);
message_time.setText(getMomentAgo(message.getSentAt()));
imageView.setId(id);
chat_messages_view_panel.addView(v);
scrollChatToBottom();
}catch (Exception ignored)
{
}
}
private void addTheirMessage(Message message)
{
try {
View v = LayoutInflater.from(chatActivity.this).inflate(R.layout.their_message, null);
TextView sender_name_view = v.findViewById(R.id.sender_name_view);
TextView message_view = v.findViewById(R.id.sender_message_body);
TextView message_time = v.findViewById(R.id.received_message_box_time);
sender_name_view.setText(message.getSentByName());
message_view.setText(message.getContent());
message_time.setText(getMomentAgo(message.getSentAt()));
chat_messages_view_panel.addView(v);
scrollChatToBottom();
}catch (Exception ignored)
{
}
}
private void addMyMessage(Message message)
{
try {
View v = LayoutInflater.from(chatActivity.this).inflate(R.layout.my_message, null);
TextView message_view = v.findViewById(R.id.my_message_body);
TextView message_time = v.findViewById(R.id.sent_message_box_time);
message_view.setText(message.getContent());
message_time.setText(getMomentAgo(message.getSentAt()));
chat_messages_view_panel.addView(v);
scrollChatToBottom();
}catch (Exception ignored)
{
}
}
public void scrollChatToBottom() {
chat_messages_scroll_view.post(new Runnable() {
#Override
public void run() {
chat_messages_scroll_view.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
private void OpenGallery()
{
Intent galleryIntent = new Intent();
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, GalleryPick);
}
#SuppressLint("SimpleDateFormat")
public String getMomentAgo(String date_time){
try{
SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy MM, dd HH:mm:ss:SSS a");
SimpleDateFormat destFormat = new SimpleDateFormat("dd MMM, HH:mm a");
Date convertedDate = sourceFormat.parse(date_time);
if (convertedDate != null) {
return destFormat.format(convertedDate);
}
}catch (Exception ignored){}
return "";
}
public void imageClick(View view)
{
Dialog builder = new Dialog(this);
builder.requestWindowFeature(Window.FEATURE_NO_TITLE);
builder.getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.TRANSPARENT));
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
//nothing;
}
});
ImageView imageView = new ImageView(this);
Picasso.get().load(imagesUrl.get(view.getId())).into(imageView);
builder.addContentView(imageView, new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
builder.show();
}
public void loadMessages(){
FirebaseDatabase.getInstance().getReference().child("Messages").child(Prevelent.onlineUser.getEmail()).
addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot)
{
for(DataSnapshot item: snapshot.getChildren())
{
Message message = item.getValue(Message.class);
if(!message_ids.contains(message.getId()))
{
message_ids.add(message.getId());
addMessage(message);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
You can follow this tutorial:
Send Device-to-Device Push Notifications Without Server-side Code
Update
You can Listen for a database specific child and show notification when there is a change happens (Simulating Server Push notification)
I am trying to make a social app .. and I want when the user clicks the edit category database should be updated to the new value .. but it is like static not changing to new value .. I don't know the problem in logic or in the code ..
private void showCategoryUpdateDialog(String Key) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("تغيير " + Key);
LinearLayout linearLayout = new LinearLayout(getActivity());
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setPadding(15, 10, 15, 10);
RadioButton radioButton = new RadioButton(getActivity());
radioButton.setText("علمي علوم");
RadioButton radioButton2 = new RadioButton(getActivity());
radioButton2.setText("علمي رياضة");
RadioButton radioButton3 = new RadioButton(getActivity());
radioButton3.setText("أدبي");
linearLayout.addView(radioButton);
linearLayout.addView(radioButton2);
linearLayout.addView(radioButton3);
builder.setView(linearLayout);
builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String value = radioButton.getText().toString().trim();
String value2 = radioButton2.getText().toString().trim();
String value3 = radioButton3.getText().toString().trim();
if (!TextUtils.isEmpty(value)) {
pd.show();
HashMap<String, Object> result = new HashMap<>();
result.put(Key, value);
databaseReference.child(user.getUid()).updateChildren(result)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
pd.dismiss();
Toast.makeText(getActivity(), "Updated...", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
pd.dismiss();
Toast.makeText(getActivity(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} else {
Toast.makeText(getActivity(), "Please enter " + Key, Toast.LENGTH_SHORT).show();
}
if (!TextUtils.isEmpty(value2)) {
pd.show();
HashMap<String, Object> result2 = new HashMap<>();
result2.put(Key, value2);
databaseReference.child(user.getUid()).updateChildren(result2)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
pd.dismiss();
Toast.makeText(getActivity(), "Updated...", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
pd.dismiss();
Toast.makeText(getActivity(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} else {
Toast.makeText(getActivity(), "Please enter " + Key, Toast.LENGTH_SHORT).show();
}
if (!TextUtils.isEmpty(value3)) {
pd.show();
HashMap<String, Object> result3 = new HashMap<>();
result3.put(Key, value3);
databaseReference.child(user.getUid()).updateChildren(result3)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
pd.dismiss();
Toast.makeText(getActivity(), "Updated...", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
pd.dismiss();
Toast.makeText(getActivity(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} else {
Toast.makeText(getActivity(), "Please enter " + Key, Toast.LENGTH_SHORT).show();
}
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();
}
In this picture have more details
Emulator
And this GIF from my Database
https://media.giphy.com/media/ZY36QuzJsdXIhIQh7k/giphy.gif
first: make sure that the new value is stored in the database (from the console)
second: after the update is completed onCompleteListener get the data again.
you can listen for this field changes in real-time which could be better than getting the data after every update.
I have a code:
#Override
protected void onCreate(Bundle savedInstanceState) {
.........
listViewMyAccountSettings = (ListView) findViewById(R.id.listViewMyAccountSettings);
arrayList = new ArrayList();
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, arrayList);
listViewMyAccountSettings.setAdapter(arrayAdapter);
arrayAdapter.notifyDataSetChanged();
listViewMyAccountSettings.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0){
showAlertUsername();
} else if (position == 1){
showAlertAge();
}
......................
}
});
.................
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("userdata").child(myEmail).child("username");
myRef.addValueEventListener(new ValueEventListener() {
#SuppressLint("SetTextI18n")
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
username = dataSnapshot.getValue(String.class);
arrayList.add("Your username: " + username);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("TAG", "Failed to read value.", error.toException());
}
});
There is showAlertUsername method:
private void showAlertUsername() {
alertDialogBuilder = new AlertDialog.Builder(
MyAccountSettings.this);
input = new EditText(MyAccountSettings.this);
lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
alertDialogBuilder.setView(input);
alertDialogBuilder.setPositiveButton("Discard",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
Toast.makeText(getApplicationContext(), "No changes were made",
Toast.LENGTH_SHORT).show();
}
});
alertDialogBuilder
.setTitle("USERNAME")
.setMessage("Enter new username")
.setCancelable(false)
.setNegativeButton("Change",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (!input.getText().toString().isEmpty()) {
mDatabase.child("userdata").child(myEmail).child("username").setValue(input.getText().toString());
Toast.makeText(getApplicationContext(), "Your username was changed successfully",
Toast.LENGTH_LONG).show();
listViewMyAccountSettings.invalidateViews();
} else {
Toast.makeText(getApplicationContext(), "Username can't be empty. No changes were made",
Toast.LENGTH_LONG).show();
}
}
});
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
And I want to update particular field in list view when I change value(and set it into database). Problem is that when I change value in database it adds a new item to list view with new value? Is there a way to update the old one without restarting an activity? Thanks.
Every time the firebase data is changed you add a new item to the list:
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
username = dataSnapshot.getValue(String.class);
arrayList.add("Your username: " + username);
}
Clear the list if before that if you want to have a single entry.
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
arrayList.clear();
username = dataSnapshot.getValue(String.class);
arrayList.add("Your username: " + username);
arrayAdapter.notifyDataSetChanged();
}
You would change the data if your current ArrayList contains otherwise just add the new one:
public void onDataChange(DataSnapshot dataSnapshot) {
username = dataSnapshot.getValue(String.class);
String item = "Your username: " + username;
if(arrayList.contains(item)) {
//if current arrayList contains the item just change it
arrayList.set(arrayList.indexOf(item), item);
} else {
//otherwise add the new one
arrayList.add(item);
}
//assuming your data is mutable
arrayAdapter.notifyDataSetChanged();
}
Use ChildEventListener instead of ValueEventListener.ChildEventListener gives the following over methods,
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
// here in dataSnapshot you will the detail for which the value is changed,using this you can update the list.
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
#Override
public void onCancelled(DatabaseError databaseError) {}
#Priya thanks a used a piece of your answer, the code now looks this way and it is doing what it should.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("userdata").child(myEmail);
myRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
if (dataSnapshot.getKey().equals("username")) {
username = (String) dataSnapshot.getValue();
arrayList.add("Username: " + username);
} else if (dataSnapshot.getKey().equals("age")) {
age = (String) dataSnapshot.getValue();
arrayList.add("Age: " + age);
} else if (dataSnapshot.getKey().equals("gender")) {
gender = (String) dataSnapshot.getValue();
arrayList.add("Gender: " + gender);
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {
if (dataSnapshot.getKey().equals("username")) {
username = (String) dataSnapshot.getValue();
arrayList.set(2, "Username: " + username);
} else if (dataSnapshot.getKey().equals("age")) {
age = (String) dataSnapshot.getValue();
arrayList.set(0, "Age: " + age);
} else if (dataSnapshot.getKey().equals("gender")) {
gender = (String) dataSnapshot.getValue();
arrayList.set(1, "Gender: " + gender);
}
arrayAdapter.notifyDataSetChanged();
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
Using Firebase Database.
I have a database which stores the registration information for patients.
While registering a new patient, i'm checking whether the person is already registered or not.
The function below checks if a registration for that person is already made or not.
I'm checking this by going to "Users/Phone_no/Patient_name".
If the DataSnapshot is not null registration is already there.
private boolean checkAlreadyRegistered(){
final boolean[] alreadyRegistered = {false};
/*Get the reference*/
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "onDataChange: " + dataSnapshot);
if (dataSnapshot.getValue() != null) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Record Already Exists");
builder.setMessage("The current patient is already registered");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
alreadyRegistered[0] = true;
}
});
builder.create();
builder.show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
}
});
return alreadyRegistered[0];
}
From saveInDatabase i'm calling the above function
void saveInDatabase(Long patient_id) {
boolean alreadyRegistered = checkAlreadyRegistered();
if (alreadyRegistered) {
resetRegisterFields();
return;
}
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Current_registered_users");
mDatabaseReference.setValue(patient_id + 1);
childDetails.setPatient_id(patient_id);
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users");
Log.d(TAG, "saveInDatabase: "+mDatabaseReference);
mDatabaseReference.child(childDetails.getPhone()).child(childDetails.getPatientName()).child("Registration Details").setValue(childDetails);
Button bt = (Button) getView().findViewById(R.id.buttonRegister);
resetRegisterFields();
progressDialog.dismiss();
displayPid(patient_id);
bt.setEnabled(true);
.
.
}
What i want to do- Check if a registration based on phone_no/Patient_name is already made or not, if not save the details.
Problem - When a new registration is made it is added to the database, but after that the message "..Already registered", from checkAlreadyRegistered() ->onDataChange is displayed.
Why is that message coming, and how solve it?
All data reading in Firebase happens asynchronously, so I recommend you change your code to something that looks like this:
private void checkAlreadyRegistered(){
/*Get the reference*/
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "onDataChange: " + dataSnapshot);
if (dataSnapshot.getValue() != null) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Record Already Exists");
builder.setMessage("The current patient is already registered");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
resetRegisterFields();
}
});
builder.create();
builder.show();
}
else
{
saveInDatabase(patient_id); //TODO change this accordingly
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
}
});
}
And your save method:
void saveInDatabase(Long patient_id) {
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Current_registered_users");
mDatabaseReference.setValue(patient_id + 1);
childDetails.setPatient_id(patient_id);
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users");
Log.d(TAG, "saveInDatabase: "+mDatabaseReference);
mDatabaseReference.child(childDetails.getPhone()).child(childDetails.getPatientName()).child("Registration Details").setValue(childDetails);
Button bt = (Button) getView().findViewById(R.id.buttonRegister);
resetRegisterFields();
progressDialog.dismiss();
displayPid(patient_id);
bt.setEnabled(true);
.
.
}
You have to wait for the response from Firebase. You can add a Callback to run the rest of your code once it's been retrieved. Do something like this:
Create an interface called ServerCallback:
public interface ServerCallback
{
void onSuccess(boolean result);
}
In your checkAlreadyRegistered() method, add the callback so it runs once the data is retrieved from Firebase:
private void checkAlreadyRegistered(final ServerCallback callback){
final boolean[] alreadyRegistered = {false};
/*Get the reference*/
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "onDataChange: " + dataSnapshot);
if (dataSnapshot.getValue() != null) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Record Already Exists");
builder.setMessage("The current patient is already registered");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
alreadyRegistered[0] = true;
callback.onSuccess(alreadyRegistered[0]);
}
});
builder.create();
builder.show();
}
else
callback.onSuccess(alreadyRegistered[0]);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
}
});
}
Then in your saveInDatabase(), wait for the callback, then run the rest of your code:
void saveInDatabase(Long patient_id) {
boolean alreadyRegistered = checkAlreadyRegistered(new ServerCallback() {
#Override
public void onSuccess(boolean result)
{
if (alreadyRegistered) {
resetRegisterFields();
return;
}
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Current_registered_users");
mDatabaseReference.setValue(patient_id + 1);
childDetails.setPatient_id(patient_id);
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users");
Log.d(TAG, "saveInDatabase: "+mDatabaseReference);
mDatabaseReference.child(childDetails.getPhone()).child(childDetails.getPatientName()).child("Registration Details").setValue(childDetails);
Button bt = (Button) getView().findViewById(R.id.buttonRegister);
resetRegisterFields();
progressDialog.dismiss();
displayPid(patient_id);
bt.setEnabled(true);
.
.
});
}
I am working on a project in which we enter an email and that is checked with the emails present in different tables of the database. Depending upon tables in which the entered email is present I want to display a list of check boxes in a dialog box on clicking a button. My problem is the names of check boxes get updated only on the second click and on further clicks the order of names change. I am not able to figure out this and spent many hours in same. Please help!
MainActivity.java
public class MainActivity extends AppCompatActivity {
public EditText et;
public Main2Activity act;
private String s;
private String[] st = {"","",""};
private int i,j;
private Boolean x;
private String url1 = "http://192.168.56.1:80/axis/results.json";
private String url2 = "http://192.168.56.1:80/hdfc/results.json";
private String url3 = "http://192.168.56.1:80/sbi/results.json";
private ProgressDialog pDialog;
private static String TAG = MainActivity.class.getSimpleName();
private String[] items= {"","",""};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//mail entered into the edittext
et = (EditText)findViewById(R.id.editText);
j=0;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// on click
public void makeJsonArrayRequest(View view) {
j=0;
s=et.getText().toString();//email to string
JsonArrayRequest req1 = new JsonArrayRequest(url1,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
try {
for (int i = 0; i < response.length(); i++) {
JSONObject person = (JSONObject) response.get(i);
String email = person.getString("email");
if(email.equals(s)){
System.out.println("Axis");
//if present in the table add to list
addItem("AXIS");
}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
JsonArrayRequest req2 = new JsonArrayRequest(url2,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
try {
for (int i = 0; i < response.length(); i++) {
JSONObject person = (JSONObject) response.get(i);
String email = person.getString("email");
if(email.equals(s)) {
System.out.println("HDFC");
addItem("HDFC");
}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
JsonArrayRequest req3 = new JsonArrayRequest(url3,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
try {
for (int i = 0; i < response.length(); i++) {
JSONObject person = (JSONObject) response.get(i);
String email = person.getString("email");
if(email.equals(s)){
System.out.println("SBI");
addItem("SBI");}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
AppController.getInstance().addToRequestQueue(req1);
AppController.getInstance().addToRequestQueue(req2);
AppController.getInstance().addToRequestQueue(req3);
dialogadd();
}
public void addItem(String s)
{
items[j]=s;
j++;
}
public void dialogadd()
{
Dialog dialog;
final ArrayList itemsSelected = new ArrayList();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select banks you want to connect to: ");
builder.setMultiChoiceItems(items, null,
new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog, int selectedItemId,
boolean isSelected) {
if (isSelected) {
itemsSelected.add(selectedItemId);
} else if (itemsSelected.contains(selectedItemId)) {
itemsSelected.remove(Integer.valueOf(selectedItemId));
}
}
})
.setPositiveButton("Done!", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
//Your logic when OK button is clicked
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
}
});
dialog = builder.create();
dialog.show();}
}
here is the log cat
logcat
on first click
on second click
on third click
AppController.getInstance().addToRequestQueue(req1); // this will take some time get data
AppController.getInstance().addToRequestQueue(req2); // even this will take some time get data
AppController.getInstance().addToRequestQueue(req3); //last this also will take some time get data
dialogadd(); // but this is an instant call. which will show the dialog, since previous all three call are pending your data get shown unless they complete.
solution : use below call to show the dialog
JsonArrayRequest req3 = new JsonArrayRequest(url3,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
try {
for (int i = 0; i < response.length(); i++) {
JSONObject person = (JSONObject) response.get(i);
String email = person.getString("email");
if(email.equals(s)){
System.out.println("SBI");
addItem("SBI");}
// use this last call show dialog
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
Advice
use Future request in volley, i think wt you need is synchronous call one after another