So, this is how my Firebase database looks like:
I am currently trying to read the value of UserInformation/Shift/zTZ0U1K8aGb6bP94YTUA50ZwIlx2/Shift in order to set the value of ShiftInformation/1514855312873/Team/zTZ0U1K8aGb6bP94YTUA50ZwIlx2 to null.
When I press a button "buttonMyShift", I need to read the value "1514855312873" because it was generated from System.getCurrentTimeMillis().
I have been trying to accomplish that by changing the value inside a "onDataChange" method, ut the app either crashes or deletes only UserInformation/Shift.
Here is my activity code:
if (view == buttonMyShift){
final FirebaseUser user = mAuth.getCurrentUser();
final FirebaseDatabase database = FirebaseDatabase.getInstance();
databaseReference = database.getReference("UserInformation/Shift/").child(user.getUid()).child("Shift");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
//Read the value of UserInformation/Shift/user.getUid()/Shift
SHIFT uShift = dataSnapshot.getValue(SHIFT.class);
//Setting the value of userShift to UserInformation/Shift/user.getUid()/Shift
String userShift = uShift.toString().trim();
//Setting the value of ShiftInformation/userShift/Team/user.getUid() to null
mReference = database.getReference("ShiftInformation").child(userShift).child("Team").child(user.getUid());
mReference.setValue(null);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
//set UserInformation/Shift/user.getUid to null
SHIFT nshift = new SHIFT(null);
databaseReference.setValue(nshift);
Toast.makeText(MainMenuActivity.this,"Adeus!",Toast.LENGTH_SHORT).show();
//leave the activity
Intent intent = new Intent(MainMenuActivity.this,BadgeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(intent);
}
Thanks For The Help!
To get the value of your Shift field, which is 1514855312873, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference shiftRef = rootRef.child("UserInformation").child("Shift").child(user.getUid()).child("Shift");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String shift = dataSnapshot.getValue(String.class);
Log.d("TAG", shift);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
shiftRef.addListenerForSingleValueEvent(eventListener);
The output will be:
1514855312873
Your DatabaseReference was correct but the problem in your code is that you are using getChildren() method when there is no need.
Related
I've been trying to retrieve just the child data from here but when i debug it shows null on each object, I'm not sure why, please help.
I've followed some instructions here on Stack overflow but i can't seem to get a solution.
My data on firebase looks like this:
Here is my code:
FirebaseAuth mFirebaseAuth = FirebaseAuth.getInstance();
FirebaseUser mFirebaseUser = mFirebaseAuth.getCurrentUser();
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference().child("the-root-db");
DatabaseReference mFirebaseDbReferenceCurrentUser = dbRef.child(mFirebaseUser.getUid());
DatabaseReference userSettingTable = mFirebaseDbReferenceCurrentUser.child("UserSetting");
userSettingTable.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot userSettingFromDb : dataSnapshot.getChildren()) {
mDbPrice = (String) userSettingFromDb.child("currencyPrice").getValue();
mDbCurrencyId = (String) userSettingFromDb.child("currencyId").getValue();
mDbUserTrackPrice = (String) userSettingFromDb.child("userSettingCurrencyValue").getValue();
break;
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("Query Db", databaseError.toString());
}
});
Since you're attaching a ValueListener to a specific node, you will get a DataSnapshot with only that node. This means you don't need to loop over its children.
userSettingTable.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mDbPrice = dataSnapshot.child("currencyPrice").getValue(String.class);
mDbCurrencyId = dataSnapshot.child("currencyId").getValue(String.class);
mDbUserTrackPrice = dataSnapshot.child("userSettingCurrencyValue").getValue(String.class);
}
I am using Firebase for my Android app. In the code below,
DatabaseReference rootReference = FirebaseDatabase.getInstance().getReference();
matchReference = rootReference.child("tournaments");
userReference = rootReference.child("Users").child(deviceID);
userReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot snapshot : dataSnapshot.getChildren()) {
if(snapshot.child(matchList.get(position).getId()).exists()) {
//If the user has Starred this game
isStarred = true;
} else { isStarred = false; }
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I get a "No Such instance field" error in the userReference field. When I debug it, it gives me the correct database path, but it does not enters the addValueEventListener function.
My database looks like
and another child called "starredGames" will be added in my code.
Why is it giving me the error?
The correct way of getting the value of your deviceID is:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference deviceIDRef = rootRef.child("Users").child("6610609cfc2c7945");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String deviceID = dataSnapshot.child("deviceID").getValue(String.class);
Log.d("TAG", deviceID);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
deviceIDRef.addListenerForSingleValueEvent(eventListener);
I have this data structure:
The red arrows points at animal IDs, and the blue arrow points at user IDs. Every user have one or many animals.
I have tried different methods for showing only the animals that have id that is stored in the current user node.
Example: If I have UID = 48onHXIxgDP465j5WW16oo7psNm2 (the first one in "users") I want to show the data from: "dog2" and "dog3".
Now iIhave the following code that gets snapshot from the "animals" node in the database, and then gets data from every child.
myAnimalRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
list = new ArrayList<AnimalCard>();
for(DataSnapshot dataSnapshot1 :dataSnapshot.getChildren()){
AnimalCard value = dataSnapshot1.getValue(AnimalCard.class);
AnimalCard animal = new AnimalCard();
String name = value.getName();
int age = value.getAge();
String url = value.getUrl();
animal.setName(name);
animal.setAge(age);
animal.setUrl(url);
list.add(animal);
}
recyclerViewSetAdapter();
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG1, "failed to read value: " + databaseError.toException());
}
});
How can get my code to filter out every animal that does not have their ID in the user node?
The reason I want to make the user get access with an UID stored in the database is because later on I want to make it so that multiple users can get access to the same animal.
To achieve this, you need to query your database twice. Please use the following code:
FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
String uid = firebaseUser.getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = usersRef.child("users").child(uid);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String aid = ds.getKey();
DatabaseReference animalRef = rootRef.child("animals").child(aid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dSnapshot) {
int age = dSnapshot.child("age").getValue(Integer.class);
String name = dSnapshot.child("name").getValue(String.class);
String url = dSnapshot.child("url").getValue(String.class);
Log.d("TAG", age + " / " + name + " / " + url);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
animalRef.addListenerForSingleValueEvent(valueEventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
uidRef.addListenerForSingleValueEvent(eventListener);
In which uid is the id of the logged-in user and aid is the id of the animal. Your output will be:
11 / dog1 / http...
12 / dog2 / http...
Hope you find this helpfull.!
Get Object in Your Model Class and Store that Object in List for Further user.!
You can get specific object as well simple using
mdatabaseRef.child("animals").orderByChild().equalTo("value")
and also you can add check on key by orderByKey()
private FirebaseAuth mAuth;
private FirebaseDatabase mdatabase;
private DatabaseReference mdatabaseRef;
mAuth = FirebaseAuth.getInstance();
mdatabase = FirebaseDatabase.getInstance();
mdatabaseRef = mdatabase.getReference();
ArrayList<User> allUserList = new ArrayList<>();
Array<Animal> allAnimalList=new ArrayList<>();
mdatabaseRef.child("animals").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
String key = childSnapshot.getKey();
Animal animal = childSnapshot.getValue(Animal.class);
allAnimalList.add(animal );
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mdatabaseRef.child("users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
String key = childSnapshot.getKey();
User user = childSnapshot.getValue(User .class);
allUserList.add(user);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I ended up taking Alex Mamo's answer and tweak with a litte bit.
This is the code i'am using:
uid = currentUser.getUid();
mRootRef = FirebaseDatabase.getInstance().getReference();
final DatabaseReference myUserRef = mRootRef.child("users").child(uid);
Log.d(TAG1, uid);
myUserRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
list = new ArrayList<AnimalCard>();
for(DataSnapshot ds : dataSnapshot.getChildren()){
String aid = ds.getKey();
DatabaseReference myAnimalRef = mRootRef.child("animals");
Query query = myAnimalRef.orderByKey().equalTo(aid);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds2 : dataSnapshot.getChildren()){
AnimalCard value = ds2.getValue(AnimalCard.class);
AnimalCard animal = new AnimalCard();
String name = value.getName();
int age = value.getAge();
String url = value.getUrl();
animal.setName(name);
animal.setAge(age);
animal.setUrl(url);
list.add(animal);
}
recyclerViewSetAdapter();
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The main difference is that i'am using a query to filter out every Animal that does not have the aID that the currentUser have.
I have Firebase data organized in the below format. When I'm trying to fetch data using the below code, it just never enters onDataChange, even though I have data in Firebase at that path.
Please ignore the list part, in the log I am able to see right path of Firebase, i.e.:
conversation/8masp4NLZrYL4HpziIU7uUZjRd73/8masp4NLZrYL4HpziIU7uUZjRd73
DatabaseReference databaseReferenceAdapter = FirebaseDatabase.getInstance().getReference();
DatabaseReference conversation2Ref = databaseReferenceAdapter.child("conversation").child(currentUser).child(userListRef.get(position));
Log.d(TAG,"Data binding++++" + conversation2Ref.getRef().toString());
conversation2Ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG,"Data changed");
Conversation conversationInfo = dataSnapshot.getValue(Conversation.class);
mConversationList.add(position,conversationInfo);
Log.d(TAG,"Data changed");
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG,"Data error");
}
});
To get those values, instead of using Conversation.cass, you can use the String.class like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference yourRef = rootRef.child("conversation").child("8masp4NLZrYL4HpziIU7uUZjRd73").child("8masp4NLZrYL4HpziIU7uUZjRd73");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String message = dataSnapshot.child("message").getValue(String.class);
long notificationCount = dataSnapshot.child("notificationCount").getValue(Long.class);
long profileId = dataSnapshot.child("profileId").getValue(String.class);
String profileName = dataSnapshot.child("profileName").getValue(String.class);
long time = dataSnapshot.child("time").getValue(String.class);
String type = dataSnapshot.child("type").getValue(String.class);
Log.d("TAG", message);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
yourRef.addListenerForSingleValueEvent(eventListener);
child(userListRef.get(position));
The above is wrong, according to the database you have random push() key under the userid. So, you have to retrieve the push key and add it to the child.
to retrieve the key:
String key=conversation2Ref.push().getKey()
then in query do:
child(key)
I'm a rookie regarding firebase and android.
After reading for a while I have raise a question regarding my code:
I'm not able to read information from my firebase database.
here's my code:
#Override
protected void onStart() {
super.onStart();
mDatabase = FirebaseDatabase.getInstance().getReference();
DatabaseReference referenceArtista = mDatabase.child("artists");
final List<Pintura> pinturaList = new ArrayList<Pintura>();
referenceArtista.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot artistaSnapshot: dataSnapshot.getChildren()) {
Artista artista = artistaSnapshot.getValue(Artista.class);
pinturaList.addAll(artista.getPinturaList());
}
RecyclerView recyclerViewPintura = (RecyclerView)findViewById(R.id.recyclerView);
recyclerViewPintura.setHasFixedSize(true);
recyclerViewPintura.setLayoutManager(new LinearLayoutManager(getBaseContext(), LinearLayoutManager.VERTICAL,false));
AdapterPintura adapterPintura = new AdapterPintura(getBaseContext(),pinturaList);
recyclerViewPintura.setAdapter(adapterPintura);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
My database structure looks something like this:
Database
I've been debugging and I'm seeing that the list at the end of the foreach cycle, returns null. (hence I'm greeted with a NullPointerException and the app crashes)
Thanks in advance :)
You are getting null because List<Pintura> pinturaList = new ArrayList<Pintura>(); is declared outside the onDataChange() method. You need to declare and use it inside that method and outside the for loop, otherwise is null, due the asynchronous behaviour of the method, which is called before you even add those Artista class objects to the list.
To solve this, please use this code:
referenceArtista.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final List<Pintura> pinturaList = new ArrayList<Pintura>();
for (DataSnapshot artistaSnapshot: dataSnapshot.getChildren()) {
Artista artista = artistaSnapshot.getValue(Artista.class);
pinturaList.addAll(artista.getPinturaList());
}
Log.d("TAG", artista); // Here is not null
RecyclerView recyclerViewPintura = (RecyclerView)findViewById(R.id.recyclerView);
recyclerViewPintura.setHasFixedSize(true);
recyclerViewPintura.setLayoutManager(new LinearLayoutManager(getBaseContext(), LinearLayoutManager.VERTICAL,false));
AdapterPintura adapterPintura = new AdapterPintura(getBaseContext(),pinturaList);
recyclerViewPintura.setAdapter(adapterPintura);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
If you want to use that list outside onDataChange() method, please see my answer from this post.
Can you initailize your recycler vioew in onCreate method and once you get the data from the firebase just update the adapter
pinturaList = new ArrayList<Pintura>();
dataSnapshot.getChildrenCount();
//List<User> list= new ArrayList<User>();
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
Artista artista = artistaSnapshot.getValue(Artista.class);
pinturaList .add(user);
}
adapter.update(pinturaList );
Instead of addListenerForSingleValueEvent use ValueEventlistener then use forEach loop because single return single or null value if you have more than one
Try this
private DatabaseReference mFirebaseDatabase;
private FirebaseDatabase mFirebaseInstance;
mFirebaseInstance = FirebaseDatabase.getInstance();
mFirebaseDatabase = mFirebaseInstance.getReference("YOUR TABLE NAME").getRef();
mFirebaseDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
Log.v("dataSnapshot.getValue()", "" + dataSnapshot.getValue());
for (DataSnapshot dss : dataSnapshot.getChildren()) {
HashMap<String, String> map = (HashMap<String, String>) dss.getValue();
//get your values
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});