I'm using Firebase Cloud database and Firebase functions. I have the following code which sends a notification once was executed by firebase functions:
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
Log.d(TAG, "onMessageReceived: started");
Log.d(TAG, "onMessageReceived: message is: " + remoteMessage.getData());
if (FirebaseAuth.getInstance().getCurrentUser() == null) {
Log.d(TAG, "User is logged out. Will not fire notification");
return;
}
String payloadDisplayStatus = remoteMessage.getData().get("display_status");
if (payloadDisplayStatus == null) {
Log.d(TAG, "onMessageReceived: did not find a display status field");
return;
}
buildAdminBroadcastNotification(remoteMessage.getData());
}
@Override
public void onNewToken(@NonNull String token) {
sendRegistrationToServer(token);
}
@Override
public void onDeletedMessages() {
super.onDeletedMessages();
}
private void sendRegistrationToServer(final String token) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null) {
return; // Failed to get current user
}
final String usersEmail = user.getEmail();
final String usersPhoneNumber = user.getPhoneNumber();
if (usersEmail != null && !(usersEmail.isEmpty())) {
db.collection("managers").document(usersEmail).get()
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
Log.d(TAG, "addOnSuccessListener:success");
if (documentSnapshot.exists()) {
List<DocumentReference> groups = (List<DocumentReference>) documentSnapshot.get("groups");
if (groups == null || groups.size() == 0) {
Log.d(TAG, "Failed to fetch the manager group");
return;
}
DocumentReference connectedGroupDocumentRef = groups.get(0);
connectedGroupDocumentRef.collection("managers").document(usersEmail).update("tokens", FieldValue.arrayUnion(token));
} else {
Log.d(TAG, "Document does not exist");
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
Log.d(TAG, "addOnSuccessListener:failed", exception);
}
});
} else if (usersPhoneNumber != null && !(usersPhoneNumber.isEmpty())) {
db.collection("employees").document(usersPhoneNumber).get()
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
Log.d(TAG, "addOnSuccessListener:success");
if (documentSnapshot.exists()) {
List<DocumentReference> groups = (List<DocumentReference>) documentSnapshot.get("groups");
if (groups == null || groups.size() == 0) {
Log.d(TAG, "Failed to fetch the volunteer group");
return;
}
DocumentReference connectedGroupDocumentRef = groups.get(0);
connectedGroupDocumentRef.collection("employees").document(usersPhoneNumber).update("tokens", FieldValue.arrayUnion(token));
} else {
Log.d(TAG, "Document does not exist");
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
Log.d(TAG, "addOnSuccessListener:failed", exception);
}
});
}
}
The functions index.js file has the following piece of code which executes the onMessageReceived method:
let tokens = deliveredUserData.tokens;
const payload = {
data: {
display_status: 'admin_broadcast',
notification_type: 'DELIVERED',
message: deliveredUser.message,
receiver_path: deliveredUserDoc.ref.toString()
}
};
return admin.messaging().sendToDevice(tokens, payload);
The tokens is an array of all tokens of the user. My app contains two types of people - managers and employees. If user connected to manager, log out and then connected to employee (or the other way around), the notification will be sent to both of them, even though only one of the is actually connected. How can I prevent it from happening in?
EDIT: Is there some way to check if a token is of the connected user? something like:
if (!(FirebaseAuth.getInstance().getCurrentUser().verifyToken(token))) {
return; // Invalid token
}
That way I could pass the token from js to java and check it. But I didn't find a way to do it without SDK.