Duplicate child when i call push() in Firebase Realtime Database - java

I am trying to retrieve data from Firebase Realtime Database and add this data to a listview. When I call push() firebase generates two children (one inside the other) with the same unique key. This is the structure of my database:
database
That is how I save the data:
RunningSession runningSession = new RunningSession(date, activityTime, pace, timeElapsed,
finalDistance, image, tipe);
DatabaseReference reference = databaseReference.child("users").child(userUid).child("activities").push();
Map<String, Object> map = new HashMap<>();
map.put(reference.getKey(),runningSession);
reference.updateChildren(map);
This is how i retrieve the data (results in a null pointer exception):
DatabaseReference reference = databaseReference.child("users").child(userId).child("activities");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list.clear();
for (DataSnapshot snpshot : snapshot.getChildren()) {
RunningSession run = snpshot.getValue(RunningSession.class);
list.add(run);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
ListViewAdapter adapter = new ListViewAdapter(this, list);
ListView activityItems = (ListView) findViewById(R.id.activityList);
activityItems.setAdapter(adapter);

You are getting duplicate push IDs because you are adding them twice to your reference. If you only need one, then simply use the following lines of code:
RunningSession runningSession = new RunningSession(date, activityTime, pace, timeElapsed, finalDistance, image, tipe);
DatabaseReference reference = databaseReference.child("users").child(userUid).child("activities");
String pushedId = reference.push().getKey();
reference.child(pushedId).setValue(runningSession);
The code for reading that may remain unchanged.

Related

get id of node in firebase by item in recyclerView

i want to access on this point by clicking on element inside cardView
i only can reach to the point before it by using this line
reference = FirebaseDatabase.getInstance().getReference("Posts")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
String str = reference.getKey();
To get the keys of the child nodes, you'll need to load the reference and then loop over snapshot.getChildren(). So something like:
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
System.out.println(postSnapshot.getKey());
...
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
If you only want to retrieve one specific node, you'll need to know the key of that node. Typically this means that you need to keep the key of each snapshot when you read the data, and associate that with the position of each node in the recycler view. The once the user clicks on an item in the view, you look up the key based on the position they clicked, and can get that item from the database again with:
reference.child(key).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(dataSnapshot.getKey());
...
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
For some more on this, see:
Get parent key value on click of child in recyclerview from firebase database
How to getKey from Firebase using RecyclerView
How to access the KEY of child by it's position in custom Adapter class
How to delete selected child on Firebase Database Android
How do I know what I'm clicking Recycle View - Firebase detele data
FirebaseRecyclerOptions<Order> options = new FirebaseRecyclerOptions.Builder<Order()
.setQuery(query, Order.class)
.build();
adapter = new FirebaseRecyclerAdapter<Order, myOrderRecyclerViewHolder.myViewHolder>(options)
{
String key =options.getSnapshots().getSnapshot(position).getKey()
}

Cant Add value Into Array In OnSuccess()

I'm really new at android development, and trying to make app with firebase. I made signup with profile photo and pushed photo name into Database. And file to FireStore. At the bottom Code mImageUrls.add(uri.toString()); line doesn't work. But it makes toast in OnSuccess(), just I can't add data into array. I initialized Array in OnCreateView(final ArrayList<String> mImageUrls = new ArrayList<>();) like other arrays too. I need your help.
lv = (ListView) rootview.findViewById(R.id.lv_main);
final ArrayAdapter adapter = new MyAdapter(getActivity(), name_list,date,imgs);
myref = FirebaseDatabase.getInstance().getReference().child("MusiciansNonSensitive");
final ArrayList<String> mImageUrls = new ArrayList<>();
final StorageReference storageReference = FirebaseStorage.getInstance().getReference();
myref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
String name_value = postSnapshot.child("name").getValue().toString();
String province_value = postSnapshot.child("province").getValue().toString();
final String url_path = postSnapshot.child("photourl").getValue().toString();
StorageReference photo_url = storageReference.child("uploads/"+url_path);
photo_url.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
mImageUrls.add(uri.toString()); // I tried to add Log.d and it adds value every for loop, but after loop it being empty array again.
}
});
//mImageUrls.add("A");
name_list.add(name_value);
date.add(province_value);
}
Log.d("LOGGOGOGOOG",mImageUrls.toString()); // Here being empty
//Toast.makeText(getContext(),list.toString(),Toast.LENGTH_LONG).show();
lv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
addOnSuccessListener is asynchronous and returns immediately. The callback is invoked some time later, even after the loop completes and your call to setAdapter. You're going to have to rewrite the code to only set the adapter after all the URLs have been fetched asynchronously. You can wait for a bunch of tasks to complete by using Tasks.whenAll() to get a new Task that will complete after the list of tasks you provide are fully complete.

How to retrieve data child of child from firebase / Android

Here is my firebase database
Here is the info.class
Here is the insert
I want to get all the data from firebase to List View
How can i get all data under "information" data list ?
please help
db = FirebaseDatabase.getInstance();
ref = db.getReference("infomation");
protected void onStart() {
super.onStart();
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
infoList.clear();
for (DataSnapshot infoSnapshot : dataSnapshot.getChildren()){
info info = infoSnapshot.getValue(info.class);
infoList.add(info);
}
InfoList adapter = new InfoList(Welcome.this, infoList);
listViewInfo.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
In your insertion part, you need to change it like below,
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("information");
ref.child( FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(in);
but if you want to save data like save the data like
information >uid> random value > then the data
that use change data retrieving part like below
for (DataSnapshot infoSnapshot : dataSnapshot.getChildren().getChildren()){
info info = infoSnapshot.getValue(info.class);
infoList.add(info);
}

Can't get data from Firebase Database on Android

So I have a set up where I want to get data from the Database on Firebase, I can get the URL back fine but I can't get data from it. When I try to debug it reads in query.addValueEventListener but after that it just goes straight to my list adapter. I don't know it's not getting the data. I have a similar set up on my node server which works perfectly fine, but won't work on Android for some reason
final DatabaseReference database = FirebaseDatabase.getInstance().getReference();
Query query = database.child("exercises");
Log.i("Database query", database.child("exercises").toString());
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot exerciseSnapshot: dataSnapshot.getChildren())
{
List<ExerciseList> exercises = new ArrayList<ExerciseList>();
ExerciseList exerciseList = exerciseSnapshot.getValue(ExerciseList.class);
Log.i("description/name", exerciseList.getDescription() + " " + exerciseList.getName());
exercises.add(exerciseList);
adapter = new ExerciseLoadListAdapter(mActivity, exercises);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mListView.setAdapter(adapter);
its go to adapter directly because addValueEventListener() is Asynchronous listeners , its run in background !
Try this code , it may be help you !
final DatabaseReference database = FirebaseDatabase.getInstance().getReference();
//Query query = database.child("exercises");
//Log.i("Database query", database.child("exercises").toString());
database.child("exercises").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot exerciseSnapshot: dataSnapshot.getChildren())
{
List<ExerciseList> exercises = new ArrayList<ExerciseList>();
ExerciseList exerciseList = exerciseSnapshot.getValue(ExerciseList.class);
Log.i("description/name", exerciseList.getDescription() + " " + exerciseList.getName());
exercises.add(exerciseList);
}
adapter = new ExerciseLoadListAdapter(mActivity, exercises);
mListView.setAdapter(adapter)
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The Firebase do NOT get the data in the debug mode in real time. If you need some object from your firebase database you will need to get the object before. I face this problem a several times, thats why in some cases I use SQLite to store data from Firebase before i take any action. But, in a fragment you can not do that, you need the data in realtime. So you need to store the listener in a variable and use it after. Here in my Github page I have a fragment working fine.
ContatsFragment.java
[]'s

Not getting all results for RecyclerView from firebase

My app has two categories of users shop owner and buyers.
When shop owner adds a shop I use his UID and then pushkey to add a shop like this:
In the Image "83yV" and "FmNu" are the shop owners and they add 2 and 1 shop respectively.
Now for buyers, I want to show the whole list of shops in a Recycler View.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_shops_avtivity);
shopsDB = FirebaseDatabase.getInstance().getReference().child("shops");
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Shop,ShopViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Shop, ShopViewHolder>(
Shop.class,
R.layout.shop_single_layout,
ShopViewHolder.class,
shopsDB)
}
The problem is when I point my Firebase Recycler Adapter to shopDB, it returns two empty cardView like this:
When I point it to specific child like
shopsDB = FirebaseDatabase.getInstance().getReference().child("shops").child("83yV24a3AmP15XubhPGApvlU7GE2");
It returns shops add by "83yV".
How can I get the shops added by other owners also? Preferably without altering current DB or creating one DB with all shops in it within on child.
To achieve this, you need to use getChildren() method twice, once to get all the users and second to get all the shops.
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference shopsRef = rootRef.child("shops");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
for(DataSnapshot dSnapshot : ds.getChildren()) {
String name = dSnapshot.child("name").getValue(String.class);
Log.d("TAG", name);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
shopsRef.addListenerForSingleValueEvent(eventListener);
Using this code, you'll be able to display all shop names to the buyers.

Categories