I have an application where users can chat with each other. One to one. I want to give users the ability to block a particular users list from sending him messages.
A code example would be appreciated.
Assuming user 1 is trying to send message to user2.
You can use below snippet to run before sending the message.
I assume you have a users node in your firebase database containing all users in the database.
Logic: user 1 is trying to send message to user 2. If user 1 is present in block list of user 2, do not allow to send.
FirebaseDatabase database = FirebaseDatabase.getInstance();
database.getReference()
.child("users")
.child("id_of_user2")
.child("block-list") // fetching block-list of user2
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> blockList = dataSnapshot.getValue(List.class);
if (blockList.contains(id_of_user1)){
// block list of user2 contains id of user1,
// DO NOT ALLOW TO SEND MESSAGE
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Related
I want to delete user from firebase authentication and also want to delete data from real-time database if the user doesn't verify email address with in 1 hours. Deleting a user is easy but if doesn't verify in 1 hour then how could I do this? The problem is that firebase is server less.
Write and deploy a scheduled function that periodically:
Queries your database for users who have not verified (you will need a child to record that).
Delete the database record and also delete the user account.
You will need to use the Firebase Admin SDK for both of these steps.
It's so easy! just create a real-time database of the unverified user database. and when the user signup the time will be also registered in the database. So when the apps start it check the unverified users and there you write the if-else statement if the difference between time is greater than 1hour the user will be deleted.
It's so simple as I said :)
Run firebaseAuth.getCurrentUser().isEmailVerified() function inside signInWithEmailAndPassword function to see if user is verified or not. if user is verfied then only create users database otherwise give an exception and break the function, it won't save unverified users data.
firebaseAuth.signInWithEmailAndPassword(Email,Pass).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
if (firebaseAuth.getCurrentUser().isEmailVerified()){
FirebaseUser user = firebaseAuth.getCurrentUser();
Uid = user.getUid();
databaseReference = FirebaseDatabase.getInstance().getReference().child("Users");
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (!snapshot.hasChild(Uid)){
databaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child(Uid);
HashMap<String,String> userMap = new HashMap<>();
userMap.put("Name","default");
userMap.put("email",Email);
databaseReference.setValue(userMap).addOnCompleteListener(new OnCompleteListener<Void>() {
//call your function here when user sign in first time after email verification
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
//call your function when user already registered and verified
//and already saved his information to database
}else{
//show your exception here
}
}else{
//show your exception here
}
}
});
I'm developing an app. The app must able to show the latest 10 registered user detail from real-time database. That is, It removes any user older than latest 10 users. Is there any way I can do this? Right now my app is able to access the user details stored in realtime firebase.
Thanks in advance.
That sounds totally feasible. An incredibly simple way is to retrieve 11 users in your app, and then just remove the last one.
ref.orderByChild("descending_timestamp").limitToFirst(11).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int userCount = 0;
for (DataSnapshot userSnapshot: dataSnapshot.getChildren()) {
if (userCount++ > 10) {
userSnapshot.getRef().remove();
} else {
// TODO: show the user in your app
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "load users", databaseError.toException());
}
});
You'll note that I order on descending_timestamp, which is a property that you must add to the data and that allows you to sort the users in reverse chronological order. For more on this, see Firebase Data Desc Sorting in Android
In my Application I am using Firebase to retrieve the mobilnumbers of the Users. Therefore I use this code:
databaseUsers.orderByChild("uid").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
users.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
User contactlists = postSnapshot.getValue(User.class);
users.add(contactlists);
}
ContactList contactAdapter = new ContactList(ContactListActivity.this, users);
listViewContacts.setAdapter(contactAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Now I have the following question: If the number of users is high, is there a possibility to send only the mobilnumbers of your Phonebook maybe in a list? Otherwise I think the traffic to Firebase might be not so efficient?!
The other opportunity would be to send each number individually but this might be quite complex if the user has many contacts.
At the moment I get all numbers from the server but I need to filter for the right contacts AND I need to display the names of the contact.
What is the best solution to use Firebase as efficient as possible and also get the names of the contacts?
Thank you in advance!
You'll have to:
Loop through the local phone book to find the phone number of each contact.
Execute a query to Firebase for each number.
Add the resulting contact (if any) to the list/adapter and update the view.
So say you've done step 1 and have a list of phone numbers. You'd then loop through those and for each:
for (String phonenumber: phonenumbers) {
Query query = databaseUsers.orderByChild("phonenumber").equalTo(phonenumber);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User contactlists = postSnapshot.getValue(User.class);
users.add(contactlists);
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore erors
}
});
}
The call to notifyDataSetChanged() ensures that the adapter know that it needs to update the view.
While the code gets a bit convoluted, it is not as slow as you may initially fear, since Firebase pipelines the requests over a single connection. The performance will mostly depend on the number of users you have in the database, but up to a few hundreds of thousands this should be fine.
I am working on the app where I need to pull specific value from the firebase. For this case I need to pull "Score" where "uID" equals current User id. What would be a best way to do so.
Thank you for any help.
Firebase will always return full nodes. So you cannot just return the score for a user. But you can return the common node that both the score and user are under (the one starting with -K...) by using a Firebase query:
DatabaseReference leadersRef = FirebaseDatabase.getInstance().getReference("Leaders");
Query query = leadersRef.orderByChild("uID").equalTo("vUdnKx...");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot child: snapshot.getChildren()) {
System.out.println(child.getKey()+": "+child.child("Score").getValue(Long.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "onCancelled", databaseError.toException());
// ...
}
})
Note that the code loops over the snapshot in the result. That is because a query will potentially have multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
For more reading see the Firebase documentation on handling lists and sorting and filtering data.
I'm trying to create an app on Android that stores user contact info.
When the user creates a "contact card" to send to another user, I'd like it to display things I stored when registering the user, name, year, number etc.
When I push, firebase creates a unique key, and when I create a FirebaseUser it creates a uid. for ease, I save the uid as part of the user structure.
I'm now attempting to access that user using the uid, unfortunately the uid is not the key.
So, I'm trying to query.
I create a Firebaseuser
currentUser = firebaseAuth.getCurrentUser.getUid.
then I try to query by
DatabaseReference ref = firebase.getinstance().getReference("user);
ref.orderByChild("Uid").equalto(currentUser.getUid());
Is this correct? after I try to add a single valuelistener to obtain the actual values inside this user. Unfortunately this crashes. Can someone point me in the right direction?
You can use the user uid as the key to save the user info like this:
private DatabaseReference mDatabase;
// ...
mDatabase = FirebaseDatabase.getInstance().getReference();
User user = new User(name, email);
mDatabase.child("users").child(userUid).setValue(user);
Then you can get the user info like this
ValueEventListener userListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get User object and use the values to update the UI
User user= dataSnapshot.getValue(User.class);
// ...
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting User failed, log a message
Log.w(TAG, "loadUser:onCancelled", databaseError.toException());
// ...
}
};
mDatabase.child("users").child(userUid).addValueEventListener(userListener);
If this doesn't work, write the error log on the OP please ;)