How to show notification when user app run in background? - android

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

Related

Notification function not working after sending the message

I was trying to implement notification functionality in my chat application but was unable to send Notification to the receiver. Its getting failed.
Successfully able to create token in the Firebase.
private void sendNotification(String receiver, String username, String message){
DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Tokens");
Query query = tokens.orderByKey().equalTo(receiver);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
Token token = dataSnapshot.getValue(Token.class);
Data data = new Data(fAuth.getUid(), R.mipmap.ic_launcher, username +": "+message, "New Message", SenderUID);
Sender sender = new Sender(data, token.getToken());
apiServices.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(UserChatActivity.this, "Failed!!", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}

How to update an existing value in the Firebase Realtime Database?

I would to update an existing value in my Firebase Realtime Database. I have tried several ways but none have worked. Anyone know how can I fix it? I attach the structure of the db if it can be useful and the code I have written so far. Thanks in advance to everyone
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myRef = database.getReference().child("users");
myRef.orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.getValue() != null) {
//loop through the keys
Map<String, Object> hashMap = new HashMap<>();
for(DataSnapshot datasnap : snapshot.getChildren()) {
if(datasnap.child("email").getValue().toString().equals(email)) {
hashMap.put("address", "TEST1");
myRef.child(email).updateChildren(hashMap).addOnSuccessListener(new OnSuccessListener() {
#Override
public void onSuccess(Object o) {
Toast.makeText(LocationActivity.this, "Data successfully update",
Toast.LENGTH_SHORT).show();
}
});
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
You're updating the wrong location in the database, which means that either the write is now showing up in the screenshot or it is rejected (which your code doesn't handle).
To update the address of the child node you're looping over:
myRef.orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot datasnap : snapshot.getChildren()) {
datasnap.child("address").getRef().setValue("TEST1").addOnSuccessListener(new OnSuccessListener() {
#Override
public void onSuccess(Object o) {
Toast.makeText(LocationActivity.this, "Data successfully update",
Toast.LENGTH_SHORT).show();
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
The key change here is that I call getRef() on the snapshot, to get a reference to that specific location in the database.
You'll note that I also removed the two conditions, since neither of them had any effect on the outcome.
FirebaseFirestore ff = FirebaseFirestore.getInstance();
ff.collection("myCollection")
.document(myAuth.getCurrentUser().getUid())
.update("field",value)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
//for example Toast.makeText(context,getString(R.string.user_updated),Toast.LENGTH_SHORT).show();
}
}
});

How to delete specific number of nodes from firebase realtime database

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

Firebase get a value under unknown push key

How can I get that value while I know nothing about the push key?
+users
+9JZTuGUzc8bx7FLrwResWmp8L583
+anon:
+email:
+fid: <- i want to get this id without knowing push key (9JZTuGUzc8bx7FLrwResWmp8L583 )
+username:
Currently, I am trying with a null response:
FirebaseDatabase.getInstance().getReference().child("users").orderByChild("anon").equalTo(getIntent().getStringExtra(EXTRA_POST_USERNAME))
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user information
if(dataSnapshot.exists()){
User user = dataSnapshot.getValue(User.class);
fidanon = user.fid;}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
final Query query = FirebaseDatabase.getInstance().getReference().child("users").orderByChild("anon").equalTo(getIntent().getStringExtra(EXTRA_POST_USERNAME));
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot != null) {
final String fid = dataSnapshot.child("fid").getValue().toString();
Toast.makeText(getActivity(), fid, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Use this,will solve your problem.

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