How to delete specific number of nodes from firebase realtime database - android

I have an app which has a structure like
Chatrooms--------
Messages-------
Chatroomid---------
-Message1
-Message2
In this chatroom when the number of messages reaches 200 I want to delete the first 50 messages.So if the messages are 200 it will delete the messages from message1 to message50.I am using a push key for the messages.
My java code for sending message
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Map<String,Object> message = new HashMap<>();
message.put("message",messageBox.getText().toString());
message.put("imageurl",ppurl);
message.put("sender",FirebaseAuth.getInstance().getCurrentUser().getUid());
reference2.push().setValue(message).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
messageBox.setText("");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(chatroom.this, "Error" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
});
My java code for retrieving message
private void getdata() {
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
for (DataSnapshot npsnapshot : snapshot.getChildren()) {
message l = npsnapshot.getValue(message.class);
list.add(l);
}
messageAdapter.notifyDataSetChanged();
}else {
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}

You can easily add this in your existing getdata function:
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
if (snapshot.getChildrenCount() > 200) {
int count = 0;
Map<String, Object> updates = new HashMap<>();
for (DataSnapshot npsnapshot : snapshot.getChildren()) {
if (count++ <= 50) {
updates.put(npsnapshot.getKey(), null);
}
}
ref.updateChildren(updates); // this will refire onDataChange, so we'll update the UI then
}
else {
for (DataSnapshot npsnapshot : snapshot.getChildren()) {
message l = npsnapshot.getValue(message.class);
list.add(l);
}
messageAdapter.notifyDataSetChanged();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // don't ignore errors
}
});
There is also a Cloud Functions sample that can do this server-side for you btw: https://github.com/firebase/functions-samples/tree/master/limit-children

Related

is there best way to read firedatabase for recycleview in multiple child nodes?

Hi i have this database: farmerUser, user, and livelihood.
Each nodes contains information in separate nodes.
For example: i want a farmer with this specific job and gets the contact information in user node and get its job description in this another node.
This is my code. This code is working, but i wonder if there is a best way to read multiple nodes to store it to my recycleview.
investingRecycleView.setLayoutManager(new LinearLayoutManager(this.getContext()));
FirebaseDatabase.getInstance().getReference().child("farmerUser").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot1 : dataSnapshot.getChildren()) {
String id = postSnapshot1.getKey();
String farmMethod = postSnapshot1.child("farmingMethod").getValue().toString();
FirebaseDatabase.getInstance().getReference().child("ventureHeader").orderByKey().equalTo(id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot4) {
for (DataSnapshot postSnapshot3 : snapshot4.getChildren()) {
String expectedReturn = postSnapshot3.child("expectedReturn").getValue().toString();
FirebaseDatabase.getInstance().getReference().child("livelihood").orderByKey().equalTo(id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot1) {
for (DataSnapshot postSnapshot2 : snapshot1.getChildren()) {
String budget = postSnapshot2.child("budget").getValue().toString();
String farmTag = postSnapshot2.child("farmingTag").getValue().toString();
FirebaseDatabase.getInstance().getReference().child("user").orderByKey().equalTo(id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot3) {
for (DataSnapshot postSnapshot3 : snapshot3.getChildren()) {
String name = postSnapshot3.child("firstName").getValue().toString();
String lastName = postSnapshot3.child("lastName").getValue().toString();
String phoneNum = postSnapshot3.child("phoneNum").getValue().toString();
FarmerVentureListModel farmerVentureListModel = new FarmerVentureListModel("Name:"+name + " " + lastName, "Farming Method:"+farmMethod,"#"+ phoneNum, "Farming tags:"+farmTag, "Budget:"+budget,"Expected return:"+expectedReturn);
list.add(farmerVentureListModel);
investingRecycleView.setAdapter(farmerVentureInvestingRow);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I wonder if there is a way like join each nodes without reading the entire data to find the match

How do I modify real-time DB change to firestore code?

How do I modify the Realtime Database change to Firestore code?
Now, I am using this code to realize my function in real-time
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Saves").child(firebaseUser.getUid());
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
progressDialog.dismiss();
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
mySaves.add(snapshot.getKey());
}
readSaves();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
private void readSaves() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
progressDialog.dismiss();
postList_saves.clear();
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
PostModel postModel = snapshot.getValue(PostModel.class);
for(String id : mySaves){
if(postModel.getPostid().equals(id)){
postList_saves.add(postModel);
}
}
}
myFotoAdapter_saves.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
my DB structure
I tried to modify this code
CollectionReference ref = db.collection("Saves");
ref.addSnapshotListener(this, new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot queryDocumentSnapshots, #Nullable FirebaseFirestoreException error) {
if(error != null){
return;
}
for(DocumentChange dc : queryDocumentSnapshots.getDocumentChanges()){
DocumentSnapshot documentSnapshot = dc.getDocument();
mySaves.add(documentSnapshot.getKey());
}
readSaves();
}
});
private void readSaves() {
db.collection("Posts").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if(!queryDocumentSnapshots.isEmpty()){
progressDialog.dismiss();
postList_saves.clear();
List<DocumentSnapshot> list = queryDocumentSnapshots.getDocuments();
for (DocumentSnapshot d : list){
PostModel post = d.toObject(PostModel.class);
postList_saves.add(post);
}
myFotoAdapter_saves.notifyDataSetChanged();
} else {
Toast.makeText(getApplicationContext(), getApplicationContext().getResources().getString(R.string.noData), Toast.LENGTH_SHORT).show();
}
}
});
}
But, it's has error error: cannot find symbol mySaves.add(documentSnapshot.getKey());
and cannot filter the data, I got all the posts not saved date.
I think I am not getting the key values.
How do I modify the code?

How to show notification when user app run in background?

I was creating a chating application with using of firebase in android studio ,my all activity working properly expect my background notification , what I wanted is,user gets notifications when other user send the message and when user unseen the message and app runs in background.
I will try this but I got notification both the times when user chatting(seen message) and when user app run in background (unseenmessage)
here is my code
apiService= Client.getClient("https://fcm.googleapis.com/").create(APIService.class);
userref =to.getStringExtra("id");
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
sendmsg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String textmsg=inputmsg.getText().toString();
if(!textmsg.equals("")){
String rand=randomString(10);
sendmessage(firebaseUser.getUid(),userref,textmsg,currentDate,currenttime,rand);
getnotifiactions(rand);
}
else{
Toast.makeText(chatscreen.this, "ENTER SOMETHING TO SEND ", Toast.LENGTH_SHORT).show();
}
inputmsg.setText("");
}
});
private void sendmessage(String sender,String receiver,String message,String currentd_d ,String currenttime,String no){
DatabaseReference reference1= FirebaseDatabase.getInstance().getReference();
HashMap<String,Object> hashMap=new HashMap<>();
hashMap.put("sender",sender);
hashMap.put("receiver",receiver);
hashMap.put("message",message);
hashMap.put("date",currentd_d);
hashMap.put("time",currenttime);
hashMap.put("isseen",false);
hashMap.put("msgid",no);
reference1.child("Chats").push().setValue(hashMap);
}
private void seenmessage(String userid)
{
reference= FirebaseDatabase.getInstance().getReference("Chats");
seenlisterner=reference.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(#NonNull #NotNull DataSnapshot snapshot)
{
for(DataSnapshot dataSnapshot:snapshot.getChildren())
{
Chat cht=dataSnapshot.getValue(Chat.class);
if(cht.getReceiver().equals(firebaseUser.getUid()) && cht.getSender().equals(userid) )
{
HashMap<String,Object> hashMap=new HashMap<>();
hashMap.put("isseen",true);
dataSnapshot.getRef().updateChildren(hashMap);
} } }
#Override
public void onCancelled(#NonNull #NotNull DatabaseError error)
{
}
}); }
here is notifications methods and calls
private void getnotifiactions(String msgid) {
reference= FirebaseDatabase.getInstance().getReference();
Query query = reference.child("Chats").orderByChild("msgid").equalTo(msgid);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull #NotNull DataSnapshot snapshot) {
for(DataSnapshot ds:snapshot.getChildren()) {
Chat ct=ds.getValue(Chat.class);
if(ct.getIsseen().equals(true)){
Toast.makeText(chatscreen.this, "Online", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(chatscreen.this, "OFFLINE", Toast.LENGTH_SHORT).show();
sendnotification(ct.getReceiver(), ct.getMessage());}
}
}
#Override
public void onCancelled(#NonNull #NotNull DatabaseError error) {
}
});
}
private void sendnotification(String receiver, String msg) {
DatabaseReference tokens=FirebaseDatabase.getInstance().getReference("Token");
Query query=tokens.orderByKey().equalTo(receiver);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull #NotNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot:snapshot.getChildren()){
String fuserid=firebaseUser.getUid();
Token token=dataSnapshot.getValue(Token.class);
Data data=new Data(firebaseUser.getUid(),R.mipmap.ic_launcher," "+msg,"New MESSAGES",userref);
Sender sender=new Sender(data,token.getToken());
apiService.sendNotification(sender).enqueue(new Callback<Myresponse>() {
#Override
public void onResponse(Call<Myresponse> call, Response<Myresponse> response) {
if(response.code()==200){
if(response.body().success != 1){
Toast.makeText(chatscreen.this,"Failed", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<Myresponse> call, Throwable t) {
}
});
}
}
#Override
public void onCancelled(#NonNull #NotNull DatabaseError error) {
}
});
}
I only wants notifications when user app run in background, not when user chatting with other user.
anyone knows how to fix this ? please help me !
If you're using FirebaseCloudMessaging to receive your push notifications, you should know that the app doesn't receive the message when the app on the background. check this docs

use two different adapters - android -fragment

I have an if and else block. if it conforms to the if condition, it will list the data in the database as imageAdapter. anasayfaAdapter will be used if elsee comes into it.
if(kisiIdd.equals(userId))
{
adapterr = new imageAdapter(getActivity(), kullaniciList);
recyclerView.setAdapter(adapterr);
adapterr.setOnItemClickListener(urunlerimFragment.this);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
kullaniciList.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Kullanici kullaniciModel = postSnapshot.getValue(Kullanici.class);
String id=kullaniciModel.getKisiId().toString();
kullaniciList.add(kullaniciModel);
kullaniciModel.setKey(postSnapshot.getKey());
}
adapterr.notifyDataSetChanged();
progressCircle.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getActivity(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
progressCircle.setVisibility(View.INVISIBLE);
}
});
}
else
{
anasayfaAdapter = new anasayfaAdapter(getActivity(), kullaniciList);
recyclerView.setAdapter(anasayfaAdapter);
anasayfaAdapter.setOnItemClickListener(urunlerimFragment.this);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
kullaniciList.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Kullanici kullaniciModel = postSnapshot.getValue(Kullanici.class);
String id=kullaniciModel.getKisiId().toString();
kullaniciList.add(kullaniciModel);
kullaniciModel.setKey(postSnapshot.getKey());
}
anasayfaAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getActivity(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
if the data in the database from the database if the imageAdapter to use to list. In the Else block, it will use the anasayfaAdapter adapter. Why would an algorithm fit?
but it does not happen. How do you have a suggestion?

Why When i get the data From Firebase it return NULL?

I'm trying to retrieve user's data from firebase using search by Email to find the user ID and use that ID to get the user's node children so i used that code to do that:
mSignin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mEmailStr = SignupActivityFragment.removeSpaces(mEmail.getText().toString());
mPasswordStr = mPassword.getText().toString();
mAuth.signInWithEmailAndPassword(mEmailStr, mPasswordStr).addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(Task<AuthResult> task) {
if (task.isSuccessful()){
getExistingUserInfo();
if(User!=null) {
sglstr = User.get("sgl");
if (sglstr.equals("true")) {
Intent intent = new Intent(getActivity(), ControllerSGL.class);
intent.putExtra("user", User);
startActivity(intent);
} else if (sglstr.equals("false")) {
Intent intent = new Intent(getActivity(), ControllerStudent.class);
intent.putExtra("user", User);
startActivity(intent);
}
}
else {
Toast.makeText(getActivity(), "NULL!!!!!!", Toast.LENGTH_SHORT).show();
}
Toast.makeText(getActivity(), "Success", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getActivity(), "Not Success", Toast.LENGTH_SHORT).show();
}
}
});
}
});
and getExistingUserInfo Method
public void getExistingUserInfo(){
FirebaseDatabase database = FirebaseDatabase.getInstance();
database.getReference().child("allUsers").orderByChild("emailAddress")
.equalTo(mEmailStr)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
uid = childSnapshot.getKey();
Log.v("HimaAbosalem",uid);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
database.getReference("allUsers").child(uid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//get user data from dataSnapshot
User=(HashMap<String,String>)dataSnapshot.getValue();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I need to use HashMap to send the data throw intent, but i gives me that java.lang.NullPointerException: Can't pass null for argument 'pathString' in child() at this part of getExistingUserInfo method
database.getReference("allUsers").child(uid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//get user data from dataSnapshot
User=(HashMap<String,String>)dataSnapshot.getValue();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
i thought the problem was uid value equal null but i made a log and it's not, and i tried to send that uid throw an intent to another activity and i recieved it to found it's not null but when i tried to get the data in that new Activity it gives the same Error!!!
I solved this problem by divide the getExistingUserInfo to two separate Function and call the function that get allUsers at onDataChange to guarantee that user's id returns
that's code after Edited:
public void getExistingUserInfo(){
FirebaseDatabase database = FirebaseDatabase.getInstance();
database.getReference().child("allUsers").orderByChild("emailAddress")
.equalTo(mEmailStr)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
uid = childSnapshot.getKey();
Log.v("HimaAbosalem",uid);
}
getUser(uid);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
public void getUser(String uid){
database.getReference("allUsers").child(uid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//get user data from dataSnapshot
User=(HashMap<String,String>)dataSnapshot.getValue();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}

Categories

Resources