Looked at many solutions and can't seem to find one in order to retrieve nodes as an Array
mDatabase = FirebaseDatabase.getInstance().getReference("users");
mDatabase.child("users").child(auth.getUid());
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
GenericTypeIndicator<List<String>> t = new GenericTypeIndicator<List<String>>() {};
List<String> yourStringArray = dataSnapshot.getValue(t);
Log.w(TAG, "users array: " + yourStringArray);
}
In android studio I get this error on t:
Cannot resolve method'getValue(com.firebase.client.GenericTypeIndicator<java.util.List<java.lang.String>>)'
My database structure: https://gyazo.com/9f2109d3d5c699329b74d6a6ed8279e8
Alternative solution to return using getValue but cannot convert to array or list...
mDatabase = FirebaseDatabase.getInstance().getReference("users");
mDatabase.child("users").child(auth.getUid());
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
collectData((Map<String, Object>) dataSnapshot.getValue());
Log.w(TAG, "users array: " + dataSnapshot.getValue());
}
public String collectData(Map<String, Object> value) {
for (Map.Entry<String, Object> entry : value.entrySet()) {
users.add((Map.Entry) entry);
}
return users.toString();
}
but I really need it as an array as a hashmap is not suitable for my purposes
You're mixing up versions of the Firebase client library SDKs. You can tell by seeing this in the error message:
com.firebase.client.GenericTypeIndicator
com.firebase comes from an obsolete version. You want the ones from com.google.firebase. Remove the legacy SDK from your build.gradle and us only the new ones.
Related
I have stored ArrayList in firebase DB, is there any way to get specific record from firebase using particular id (memberId) from ArrayList
Currently, I'm able to get the tripMemberList ArrayList but I want to get specific record from ArrayList using memberId
I don't want to retrieve full ArrayList only need a single record from tripMemberList using memberId
I'm attaching a firebase DB structure below
Edit: How i add a record to firebase
TripChatDTO tripChatDTO = new TripChatDTO();
tripChatDTO.setTripId(jsonObject.getInt("travelId"));
tripChatDTO.setTripName(travelDTO.getTitle());
tripChatDTO.setTripPicUrl(jsonObject.getString("image"));
List<TripMemberDTO> memberDTOList = new ArrayList<>();
for (int i = 0; i < invitedFriendArray.length(); i++) {
JSONObject jsonObject1 = invitedFriendArray.getJSONObject(i);
TripMemberDTO dto = new TripMemberDTO();
dto.setMemberId(jsonObject1.getInt("id"));
dto.setAdmin(false);
dto.setNotification(true);
memberDTOList.add(dto);
}
// Add Admin record
TripMemberDTO tripMemberDTO = new TripMemberDTO();
tripMemberDTO.setMemberId(loggedInUser.getId());
tripMemberDTO.setAdmin(true);
tripMemberDTO.setNotification(true);
memberDTOList.add(tripMemberDTO);
// Add all Member record to travel
tripChatDTO.setTripMemberList(memberDTOList);
String channelName = "Trip-" + tripChatDTO.getTripId();
// Create tip
FirebaseDatabase.getInstance().getReference().child(TRIP).child(channelName).setValue(tripChatDTO);
it might be anywhere in the list I want to find a record using `memberId
Then loop over the children of the top element
tripMemberRef rootRef = FirebaseDatabase.getInstance().getReference()
.child("Trips/Trip-190/tripMemberList");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot c : dataSnapshot.getChildren()) {
String memberId = c.child("memberId").getValue(String.class);
Log.d("TAG", memberId);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
ref.addListenerForSingleValueEvent(eventListener);
Assuming that Trips is a direct child of the Firebase root, please use this code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = rootRef.child("Trips").child("Trip-190").child("tripMemberList").child("0");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String memberId = dataSnapshot.child("memberId").getValue(String.class);
Log.d("TAG", memberId);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
ref.addListenerForSingleValueEvent(eventListener);
But remember, Firebase is a NoSQL database which is structured as pairs of key and values. This means that every object within a Firebase database is a Map and not an ArrayList.
I'm having some issues reading from a Firebase Database.
I have a pretty simple layout
{
"lot" : {
"lot1" : "low",
"lot2" : "low",
"lot3" : "low"
}
}
Of course MyAppName { } is above this all.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getInstance().getReference();
// Read from the database
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
lotMap = (HashMap) dataSnapshot.getValue();
Log.d("[Directions Activity]: ", "Lot1 value ====== " +lotMap.get("lot"));
Iterator it = lotMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
Log.d("[Directions Activity]: ", "iterator " + pair.getKey() + " = " + pair.getValue());
System.out.println();
it.remove(); // avoids a ConcurrentModificationException
}
}
Here's what returns from log
D/[Directions Activity]:: Lot1 value ====== null //null obviously
//because key lot1 doesn't exist
D/[Directions Activity]:: lot = {lot3=low, lot2=low, lot1=low}
So to me, it looks like it's returning the string {lot3=low, lot2=low, lot1=low}, but I'd like to be able to get an array, with each value if possible.
Is this achievable??
I had the same question and this is what i used. Modifying to fit the question here
private List<String> lotList;
lotList = new ArrayList<>();
DatabaseReference reference= database.getInstance().getReference().child("lot");
Now adding value event listener
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> mData = dataSnapshot.getChildren();
for(DataSnapshot d : mData){
String lot_string = d.getValue(String.class);
lotList.add(lot_string);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
There's some tweak in your code. Your
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getInstance().getReference();
should be write like this,
DatabaseReference myRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference database = myRef.child("anyValueNameYouSpecifyInConsole");
Those 2 lines should be declare outside onCreate method. The one that you need to specify with addValueEventListener is the 2nd DatabaseReference, not the first one. So, it should looks like this from my example,
database.addValueEventListener (new ValueEventListener)
and it will import method.
If you wish the data to be displayed in a particular TextView, then just findViewById the TextView you wanna use and include it in onDataChange method like so,
String x = dataSnapshot.getValue(String.class);
textViewNameDeclared.setText(x);
And don't forget to change the security rule for reading.
you can use typecast to JSONObject and parse the JSONObject
JSONObject jsonObject= new JSONObject((Map)dataSnapshot.getValue());
JSONObject jsonObj= (JSONObject) jsonObject.get("lot");
for (Object key : jsonObj.keySet()) {
//based on you key types
String keyStr = (String)key;
Object keyvalue = jsonObj.get(keyStr);
//Print key and value
System.out.println("key: "+ keyStr + " value: " + keyvalue);
}
if you using java 8 than you use lamada expression.
Is it possible to fetch a child from an object without the entire parent in Firebase
For example, a customer registry, where I need all the "name" fields, but I do not have the user "uid". ...
Alex's answer will work (with my comment for good measure).
But you should realize that this downloads all data of all users. There is no way in the Firebase Database to download just one property of each node. So if you want an efficient way to download just the list of names, you should keep precisely that in the database: a list of names.
usernames
uid1: "Fernando"
uid2: "Alex"
That way you can read just the list of names with:
DatabaseReference usernamesRef = FirebaseDatabase.getInstance().getReference().child("usernames");
usernamesRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String uid = childSnapshot.getKey();
String name = childSnapshot.getValue(String.class);
}
Yes it's possible. Please use this code:
DatabaseReference yourRef = FirebaseDatabase.getInstance().getReference().child("usuarios");
usersRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> list = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String uId = (String) ds.getKey();
String nome = ds.getChild("nome").getValue(String.class);
list.add(nome);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
You first iterate to get those uid's and after that use them in the DatabaseReference.
Hope it helps.
What should be my query be if I want to get the list of all records which gender = 0 and userType = 1? I'm quite new to firebase and I can't find any sources that teaches compound some queries.
first of all create a node name userList and add instances of user with key 0,1,2,3 and so on like in screen shot in question. It becomes an array of userList
List<User> userList = new ArrayList<>();
Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
<User> user = postSnapshot.getValue(<User>.class);
userList .add(user);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("The read failed: " ,firebaseError.getMessage());
}
});
And you can also use Firebase RecyclerAdapter like this
Firebase is no SQL. it doesn't have where clause. You can use orderBy,startAt,endAt function to achieve filtering . See this and this.
Filter most on the server, do the rest on the client
orderBy('gender')
.startAt('0').endAt('0')
and in onDataChange
for (DataSnapshot postSnapshot: snapshot.getChildren())
{
<User> user = postSnapshot.getValue(<User>.class);
if(user.getUserType == 1)
userList .add(user);
}
I am having some issues with the Android version of my app. I completed the iOS version and am working on the Android data part. After I get the the snapshot in Swift, I can simply say something like this:
myList.addObject((snapshot.value["num"] as? String)!)
Then I have a nice list of of the numbers I need.
So far with Android it isn't that simple. Here is my how my data is structured and what I am looking for.
staffNUM
--staff
--12345677
-- num:112234
--2345689
-- num:090909
--44445677
-- num:999234
--6665689
-- num:888673
I can't change the way the data is created since the app for iOS is already being used.
Here is the question:
I have a reference to my database, which works.
mDatabase = FirebaseDatabase.getInstance().getReference();
Here is how I am calling the database after:
mDatabase.child("staffNUM/staff").addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
Log.d("Snap", "" + dataSnapshot.getValue());
StaffNum staffNum = dataSnapshot.getValue(StaffNum.class);
} else {
// something else happens
}
My results in the snapshot are:
D/Snap: {staff={12345677={num=112234},{2345689 ={num= 090909},{2345689 ={num= 090909}, {44445677={num= 999234}, {6665689 ={num= 888673}}
What is the best way to parse that data? I just need a list like I did in Swift to use in the app.
Edit:
Here is the class I added
#IgnoreExtraProperties
public class StaffNum {
public String num
public StaffNUM() {}
public StaffNUM(String num) {
this.num = num;
}
#Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put("num", num);
return results;
}
}
If I call Log.d("num: ","" + staffNUM.num);
I still get
D/num:: null
Create a Staff POJO with the fields that you need from your Firebase structure
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot d : dataSnapshot.getChildren()) {
Staff staff = d.getValue(Staff.class);
Log.d("Snap", "num: " + staff.getNum());
}
}