I want show a list of users (using RecyclerView , adapter ...) , the list contain user's info (photo , name , email ....) and also a count of the comments about this user , for the user's info I made a firebase query and I get all the info as I want
al = new ArrayList<>();
FirebaseDatabase.getInstance().getReference().child("Seeker").child(categorie).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// clear data before
al.clear();
for (DataSnapshot dataLoop : dataSnapshot.getChildren()) {
String getcity = dataLoop.child("City").getValue().toString().trim();
if (getcity.equalsIgnoreCase(City.trim())) {
p = new Person();
p.setName(dataLoop.child("Name").getValue(String.class));
p.setId(dataLoop.child("Id").getValue(String.class));
if (dataLoop.hasChild("urlToImage")) {
p.setUrl(dataLoop.child("urlToImage").getValue(String.class));
} else {
p.setImage(R.drawable.profile);
}
readData(new MyCallback() {
#Override
public void onCallback(String value) {
Log.d("TAG", value);
p.setComms(value);
}
}, dataLoop.child("Id").getValue(String.class));
al.add(p);
}
}
md = new MyAdaptor(MyClass.this, al);
rv.setAdapter(md);
}
...
...
public void readData(final MyCallback myCallback, String value) {
database.child("Review").child(value).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataLoop : dataSnapshot.getChildren()) {
count = dataLoop.getChildrenCount();
Log.d("TAG", "count = " + count);
p.setComms(String.valueOf(count));
}
myCallback.onCallback(String.valueOf(count));
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
}
public interface MyCallback {
void onCallback(String value);
}
my problem is that I want add one more info for each user , it's the count of review for each one , I tried to make another query inside the loop but as firebase calls are asynchronous
it's not working , the layout doesn't show numbers of reviews.
here is a sample of my firebase database structure
-Review
-HDGFDGDGDB (user id)
-FSETTDGDG (user who made the review)
-1 : review1
-2 : review2
-Seeker
-HDGFDGDGDB (user id)
-city : "NY"
-name : "Jhon"......
what's the best solution to combine the two queries in order to show all the info in the recyclerView.
Related
According to the documentation, we should avoid nesting data when it comes to database relationships. So I structured my data as follow:
{
"rides": {
"ride1": {
"price": "500",
"bids": {
// the value here doesn't matter, just that the key exists
"bid1": true,
"bid2": true
}
},
...
},
"bids": {
"bid1": {
"price": "550",
"ride": "ride1"
},
...
}
}
In one page of my app, the user should be able to see all "bids" that are linked to the selected "ride" in a ListView. My attempt was: Getting the keys of the bids in an arrayList and then fetching the bids by key on by one. My problem is the fact that I have to display all the bids in a listview at once.
bidsListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<String> bidskeysOfActiveRideArrayList = new ArrayList<>();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Boolean IsbidLinkedToThisRid = snapshot.getValue(Boolean.class);
if (IsbidLinkedToThisRid) {
String bidObjectId = dataSnapshot.getKey();
bidskeysOfActiveRideArrayList.add(bidObjectId);
}
}
fetchMultipleBidsByKeys(bidskeysOfActiveRideArrayList);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
databaseReference.child("rides").child(ride.getID()).child("bids").addValueEventListener(bidsListener);
The two functions are here:
private void fetchMultipleBidsByKeys(ArrayList<String> bidskeysOfActiveRideArrayList) {
ArrayList<Bid> bidsArrayList = new ArrayList<>();
for (String bid_id:bidskeysOfActiveRideArrayList){
bidsArrayList.add(getBidByKey(bid_id));
}
displayBidList(bidsArrayList);
}
private Bid getBidByKey(String bidObjectId) {
final Bid[] bidFetched = {null};
ValueEventListener bidsSingleFetcher = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
bidFetched[0] = snapshot.getValue(Bid.class);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
databaseReference.child("bids").child(bidObjectId).addListenerForSingleValueEvent(bidsSingleFetcher);
return bidFetched[0];
}
However, firebase data fetch is asyncronuous. So what is the correct way of fetching elements by a list of IDs then displaying them on a listview?
I create 2 android apps, for the user and for admin. The user app can crud the "pelanggaran", the admin app can see all the pelanggaran realtime.
Here, I am stuck in retrieving the data in real time for the admin app. Here's the database hierarchy.
this is the references: pelanggaran and user
each user has pelanggaran. so, the first child of pelanggaran is userID, then the pelanggaranID, then the values
I tried googling, I got it, but it is not real-time. Here's my code
private void refreshList(){
databaseUser = FirebaseDatabase.getInstance().getReference("User");
pelanggaranList = new ArrayList<>();
databaseUser.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
pelanggaranList.clear();
long numberUsers = dataSnapshot.getChildrenCount();
Log.w("total user", "" + numberUsers);
for (DataSnapshot dsUser : dataSnapshot.getChildren()){
User user = dsUser.getValue(User.class);
final String userId = user.getUserId();
Log.w("id user", userId);
databasePelanggaran = FirebaseDatabase.getInstance().getReference("Pelanggaran").child(userId);
databasePelanggaran.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot1) {
for (DataSnapshot dsPelanggaran : dataSnapshot1.getChildren()){
Pelanggaran pelanggaran = dsPelanggaran.getValue(Pelanggaran.class);
Log.w("id pelanggaran", userId + " : " + pelanggaran.getIdPelanggaran());
pelanggaranList.add(pelanggaran);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
PelanggaranAdapter pelanggaranAdapter = new PelanggaranAdapter(MainActivity.this, pelanggaranList);
recyclerView.setAdapter(pelanggaranAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
It can take all the values from each user but it is not real time. And sometimes the data doesn't appears. What should I do to make it realtime?
I'm building a social app. I need to display friends posts in the main feed with firebase recycler adapter. I've tried many options but I'm not been able to do this, with the code below I'm only able to load posts of the current user. I'm pasting the code here please guide me in this regard.
I'm using 2 queries one for friends and other for posts
The two database references are as follows
mUsersPostsDatabase = FirebaseDatabase.getInstance().getReference().child("posts");
mFriendsDatabase= FirebaseDatabase.getInstance().getReference().child("Friends").child(current_user_id);
The method is as follows
#Override
protected void onStart() {
super.onStart();
Query posts = mUsersPostsDatabase
.orderByChild("user_id")
.equalTo(mFriendsDatabase.getKey());
FirebaseRecyclerAdapter<CurrentUserPosts, UsersViewHolder> firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter<CurrentUserPosts, UsersViewHolder>(
CurrentUserPosts.class,
R.layout.view_user_post_layout,
UsersViewHolder.class,
posts
) {
#Override
protected void populateViewHolder(UsersViewHolder usersViewHolder, CurrentUserPosts model, int position) {
usersViewHolder.setImage_url(model.getImage_url(), getApplicationContext());
usersViewHolder.setUser_image(model.getUser_image(), getApplicationContext());
usersViewHolder.setUser_name(model.getUser_name());
usersViewHolder.setDate_time(model.getDate_time());
usersViewHolder.setDescription(model.getDescription());
}
};
mUsersList.setAdapter(firebaseRecyclerAdapter);
}
The database node are like the following
Friends ---> current_user_id ----> friend_id
Posts ----> post_id ----> date, user_id, image_url, descp......
Query friends = FirebaseDatabase.getInstance().getReference().child("Friends").child(mAuth.getCurrentUser().getUid());
friends.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String friendID = ds.getRef().getKey().toString();
Query posts = FirebaseDatabase.getInstance().getReference()
.child("posts").orderByChild("user_id").equalTo(friendID);
posts.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {
CurrentUserPosts newPost = new CurrentUserPosts();
newPost.setImage_url(singleSnapshot.child("image_url").getValue(String.class));
mPosts.add(newPost);
}
Collections.reverse(mPosts);
mUsersList.setAdapter(new UsersPostsThumbAdapter(mPosts));
}
#Override
public void onCancelled(DatabaseError databaseError) {
String errormsg = databaseError.toString();
Toast.makeText(getApplicationContext(), errormsg, Toast.LENGTH_SHORT).show();
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I am trying to sort my Firebase DB data on the Android Studio side and apply it in real-time. My codes successfully updates the view immediately when I make a manual change on my DB, but I wonder if I can sort by name using the code. I thought orderByChild was the function to do that, but it does not change the database.
Function that fetches data from firebase and displays:
private void fetchRepoData(String profileUserID) {
profileUserDatabase = repoReference.child(profileUserID);
//DatabaseReference reposReference = profileUserDatabase.child("Repos");
profileUserDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
repoListItems.clear();
repoNameList.clear();
userNameList.clear();
descriptionList.clear();
Toast.makeText(getActivity(), "changed", Toast.LENGTH_SHORT).show();
for(DataSnapshot snapshot : dataSnapshot.getChildren()) {
repoNameList.add(snapshot.getValue(RepoInfo.class).getRepoName());
userNameList.add(snapshot.getValue(RepoInfo.class).getOwner());
descriptionList.add(snapshot.getValue(RepoInfo.class).getDescription());
}
for(int i = 0; i < repoNameList.size(); i++) {
repoListItems.add(new RepositoryItem(i, repoNameList.get(i), userNameList.get(i), descriptionList.get(i)));
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Radio button for sorting by name
sortByNameRadio.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
repoReference.child("subchild").orderByChild("name");
adapter.notifyDataSetChanged();
}
}
);
When you call orderByChild() it returns a new Query object. You'll need to store a reference and attach a listener that query object.
profileUserDatabase = repoReference.child(profileUserID);
Query query = repoReference.child("subchild").orderByChild("name");
query.addValueEventListener(new ValueEventListener() {
for(DataSnapshot snapshot: dataSnapshot.getChildren()) {
System.out.println(snapshot.getKey());
...
Here member’s key in Group is User’s key.
Task: Want to fetch comida_id froenter code herem User based on Group’s member key.
Here we are trying to first fetch member keys from Group. While fetching member key we also want to fetch User and User’s comida_id while that member’s loop is going. So the scenario will be First we are going to fetch all keys from Group based on Group’s key ( for example createTime, groupName, members ). Now from that we will execute loop on members so will get member’s key. Now while fetching this member’s key in that loop, we want to fetch comida_id from User’s, which will be fetch in that loop only.
GroupKey -> get Data(createTime, groupName, members, restaurants) -> fetch members key and comida_id ( in Loop (get member key then fetch comida_id ))
*My Code
FirebaseDatabase mDatabase_gp = FirebaseDatabase.getInstance();
mDatabase_gp.getReference("Group/"+group_key).addValueEventListener(
new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Map<String, Object> valuesMap = (HashMap<String, Object>) dataSnapshot.getValue();
Map userkey = (Map) valuesMap.get("members");
Log.d("Members", String.valueOf(userkey));
for (Object ke: userkey.keySet())
{
Log.d("runfirst","First Run");
String key = String.valueOf(ke.toString());
Log.d("Member key",key);
// HERE WHAT CORRESPONDS TO JOIN
FirebaseDatabase User = FirebaseDatabase.getInstance();
User.getReference("User/"+key).addValueEventListener(
new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Map<String, Object> valuesMap = (HashMap<String, Object>) dataSnapshot.getValue();
String userid = String.valueOf(valuesMap.get("comida_id"));
Log.d("comida_id",userid);
Toast.makeText(ChatSectionActivity.this,userid,Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
}
);
}
Log.d("runlast","Last Run");
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
}
);
*
In Above code we tried to achieve same thing but here this code will fetch all member keys from group first. After fetching all members it will fetch comida_ids in another loop.. So there will be like two different loops working to fetch comida_id from members. It’s not working like join query.
GroupKey -> get Data(createTime, groupName, members, restaurants) -> fetch members key (in Loop (get member key) after then fetch comida_id .
*1) I was try this solution - How to perform join query in Firebase?
**But get this error –
Incompatible types.
Required: com.google.firebase.database.DatabaseReference
Found: com.google.firebase.database.ValueEventListener
https://i.stack.imgur.com/ljlWo.png
Firebase doesn't have join queries. And what you are doing wrong is your are referencing your data base on Fireabaseuser, which is wrong.
mdatabaseReference.child("Answer").child("Answer"+QID).orderByChild("questionId").equalTo(QID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (muftiAnswer_List.size() > 0)
muftiAnswer_List.clear();
for (DataSnapshot postsnapshot : dataSnapshot.getChildren()) {
final AnswerClass muftiAnswer = postsnapshot.getValue(AnswerClass.class);
String ide=muftiAnswer.getMuftiId(); //getting AlimId From Class object
Log.e(TAG, "Alim:"+ muftiAnswer.getMuftiId());
//Using Query to get Alim Name From Data Table.!
mdatabaseReference.child("users").child("Alim").child(ide).addListenerForSingleValueEvent(new ValueEventListener() {
#Override //.orderByChild("alimId").equalTo(user_Id)
public void onDataChange(DataSnapshot dataSnapshot) {
Log.e(TAG, "AlimNode:");
for(DataSnapshot postSnapshot:dataSnapshot.getChildren())
{
Log.e(TAG, "EqualNode:");
if(postSnapshot.getKey().equals("alimName"))
{
Log.e(TAG, "AlimNameNodeSnapShot:");
//Setting Alim Name in Current Object replcing id for name
muftiAnswer.setMuftiId(postSnapshot.getValue().toString());
}
// resultMuftiAnswer_List.add(muftiAnswer);
}//End of snapshot
}//ondata Change
#Override
public void onCancelled(DatabaseError databaseError) {
// Failed to read value
Log.w(TAG, "Failed to read value.", databaseError.toException());
}
});//End OF Alim Query
}//end of comments
circular_progress2.setVisibility(View.GONE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(Details_Activity.this, "LOLOLOL", Toast.LENGTH_SHORT).show();
}
});
You have to use nested loops for doing joins like MYSQL
Query query = reference.child("issue").orderByChild("id").equalTo(0);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// dataSnapshot is the "issue" node with all children with id 0
for (DataSnapshot issue : dataSnapshot.getChildren()) {
// do something with the individual "issues"
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Visit link for better understanding
https://firebase.googleblog.com/2013/10/queries-part-1-common-sql-queries.html