Need to add a new node "Completed" under the parent which will eventually contain all the information from the node "Requests" at end of the ride.
So basically, I need to create node "Completed" first but its not adding it.
database
{
"Requests" : {
"iowpxU6WKUWpzWJyfssSoOVCPFj2" : {
".priority" : "f8118c3k3v",
"destination" : "221 Prince William St",
"details" : {
"driver" : "nYIAHSYimJMHbMkXqDt9PQ0U3Nf2",
"location" : "27 Horsfield St",
"request status" : "accepted",
"ridePrice" : 3.75,
"rideStatus1" : "arrived at pickup",
"rideStatus2" : "rider in vehicle",
"rideStatus3" : "destination bound",
"rideStatus4" : "arrived at destination",
"rider" : "iowpxU6WKUWpzWJyfssSoOVCPFj2",
"riderPaid" : "true"
},
"Users" : {
"Drivers" : {
"nYIAHSYimJMHbMkXqDt9PQ0U3Nf2" : {
"driver" : "nYIAHSYimJMHbMkXqDt9PQ0U3Nf2",
"email" : "driver#me.com",
"name" : "driver",
"password" : "whatever",
"phone" : "5551212",
"rates" : "0"
}
},
"Riders" : {
"iowpxU6WKUWpzWJyfssSoOVCPFj2" : {
"avatarUrl" : "",
"email" : "rider#me.com",
"name" : "rider",
"password" : "whatever",
"phone" : "5551313",
"rates" : "0",
"riderId" : "iowpxU6WKUWpzWJyfssSoOVCPFj2"
}
}
}
}
addNewNode
private void addNewNode() { // TODO: ........ NOT ADDING NEW NODE :-| ..........
Toast.makeText(this, "addNewNode", Toast.LENGTH_LONG).show();
DatabaseReference newNode = FirebaseDatabase.getInstance().getReference("Completed");
newNode.child(riderId).push().addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Toast.makeText(DriverTripDetail.this, "addNewNode: onDataChange", Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Any assistance on how I can fix this would be greatly appreciated.
The Firebase Database stores values at paths. If there is no value, the path does not exist.
Your code creates a reference to /Completed/$pushID. but doesn't set any value, so the path doesn't get created. Something like this will work, since it sets a value:
newNode.child(riderId).push().setValue(true)
Related
I have the following database structure -
{
"linking" : {
"shift-assign" : { // for every shift its assigned users
"key1" : {
"111" : true,
"222" : true
},
"key2" : {
"111" : true
}
},
"user-assign" : { // for every user its assigned shifts
"111" : {
"key1" : true,
"key2" : true
},
"222" : {
"key1" : true
}
}
},
"shifts" : {
"20191117" : {
"key1" : {
"endTime" : "00:00",
"numOfEmps" : 3,
"startTime" : "00:00",
"wage" : 0
},
"key2" : {
"endTime" : "00:00",
"numOfEmps" : 1,
"startTime" : "00:00",
"wage" : 0
}
}
},
"users" : {
"111" : {
"id" : "111",
"password" : "111"
},
"222" : {
"id" : "222",
"password" : "222"
},
"99999" : {
"id" : "99999",
"password" : "123",
}
}
}
Where a user can be assigned to several shifts and a shift can contain several users.
I'm currently trying to fetch all of the users assigned to a certain shift.
So the idea was attaching a ValueEventListener to linking/shift-assign/{shift-key}, run a loop and for every user-key , reference users/{user-key} and attach an inner ValueEventListener to read user object and add it to a userList.
Something like this :
mDatabase.child("linking/shift-assign").child(shiftKey)
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for(DataSnapshot ds : dataSnapshot.getChildren()){
mDatabase.child("users").child(ds.getKey())
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot2) {
mUser user = dataSnapshot2.getValue(mUser.class);
userList.add(user);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
}
adapter = new UsersAssignedAdapter(UsersAssignedActivity.this, userList);
lv.setAdapter(adapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
I debugged it and noticed that the for loop is finished before the inner ValueEventListener is called, which is why I'm getting an empty list in my adapter. I'm guessing this is due to its asynchronous behavior.
So my question is - is there any way I can query all user ids and for each one perform another query?
I am trying to create chat app with Firebase database. I'm reading docs and watching tutorials but there is one thing I could not figure out how to do. When user sends message to another user, creating a chat room with key: "senderUserId_receiverUserId" You can see my structure below.
{
"chat_rooms" : {
"nTAHqCTmLRcLOM8CTfnHF4lRjLf2_oTLYaHMOMibh3ZqOcmpcWDtSCKp1" : {
"-KtQEGK38lhZrgnNxmqb" : {
"date" : "07/09/2017 10:28",
"message" : “Thanks for helping !”,
"photoUrl" : "http://www.clker.com/cliparts/B/R/Y/m/P/e/blank-profile-hi.png",
"receiverName" : "Ali”,
"receiverUid" : "oTLYaHMOMibh3ZqOcmpcWDtSCKp1",
"senderName" : “John”,
"senderUid" : "nTAHqCTmLRcLOM8CTfnHF4lRjLf2"
},
"-KtQEKK2BmIMzwruN-21" : {
"date" : "07/09/2017 10:28",
"message" : “Another Test Message“,
"photoUrl" : "http://www.clker.com/cliparts/B/R/Y/m/P/e/blank-profile-hi.png",
"receiverName" : “John”,
"receiverUid" : "nTAHqCTmLRcLOM8CTfnHF4lRjLf2",
"senderName" : "Ali",
"senderUid" : "oTLYaHMOMibh3ZqOcmpcWDtSCKp1"
},
"-KtQIGDk5zE4JZuE9pIQ" : {
"date" : "07/09/2017 10:45",
"message" : “Test message !“,
"photoUrl" : "http://www.clker.com/cliparts/B/R/Y/m/P/e/blank-profile-hi.png",
"receiverName" : “John”,
"receiverUid" : "nTAHqCTmLRcLOM8CTfnHF4lRjLf2",
"senderName" : "Ali",
"senderUid" : "oTLYaHMOMibh3ZqOcmpcWDtSCKp1"
}
}
},
"users" : {
"nTAHqCTmLRcLOM8CTfnHF4lRjLf2" : {
"address" : “istanbul”,
"cell_phone" : “none”,
"email" : “john#gmail.com",
"home_phone" : “none”,
"name" : “John”,
"photoUrl" : "http://www.clker.com/cliparts/B/R/Y/m/P/e/blank-profile-hi.png",
"userId" : "nTAHqCTmLRcLOM8CTfnHF4lRjLf2"
},
"oTLYaHMOMibh3ZqOcmpcWDtSCKp1" : {
"address" : “istanbul”,
"cell_phone" : “none”,
"email" : "ali#gmail.com”,
"home_phone" : “none”,
"name" : "Ali",
"photoUrl" : "http://www.clker.com/cliparts/B/R/Y/m/P/e/blank-profile-hi.png",
"userId" : "oTLYaHMOMibh3ZqOcmpcWDtSCKp1"
}
}
}
With this way everything works fine but I don't know how to list user's all conversations at list like WhatsApp's Chats page. I mean when user clicks the conversations item, related conversation will be open.
I'm sending private messages with code below:
public void sendMessageToFirebaseUser(final Context context, final ChatMessageModel chat, final String receiverFirebaseToken) {
final String room_type_1 = chat.getSenderUid() + "_" + chat.getReceiverUid();
final String room_type_2 = chat.getReceiverUid() + "_" + chat.getSenderUid();
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
databaseReference.child(Constants.ARG_CHAT_ROOMS)
.getRef()
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild(room_type_1)) {
Log.e("aaa", "sendMessageToFirebaseUser: " + room_type_1 + " exists");
databaseReference.child(Constants.ARG_CHAT_ROOMS)
.child(room_type_1)
.push()
.setValue(chat);
} else if (dataSnapshot.hasChild(room_type_2)) {
Log.e("aaa", "sendMessageToFirebaseUser: " + room_type_2 + " exists");
databaseReference.child(Constants.ARG_CHAT_ROOMS)
.child(room_type_2)
.push()
.setValue(chat);
} else {
Log.e("aaa", "sendMessageToFirebaseUser: success");
databaseReference.child(Constants.ARG_CHAT_ROOMS)
.child(room_type_1)
.push()
.setValue(chat);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Thank you for reading my post.
If you want to show a list of chat rooms for the current user, you should model your data to allow that. The easiest way to do this is to add a list of chat rooms for each user to your data model:
"userChatrooms" : {
"nTAHqCTmLRcLOM8CTfnHF4lRjLf2" : {
"nTAHqCTmLRcLOM8CTfnHF4lRjLf2_oTLYaHMOMibh3ZqOcmpcWDtSCKp1": true
},
"oTLYaHMOMibh3ZqOcmpcWDtSCKp1" : {
"nTAHqCTmLRcLOM8CTfnHF4lRjLf2_oTLYaHMOMibh3ZqOcmpcWDtSCKp1": true
}
}
Let's consider a "UserBean" with a property "emails" that is an ArrayList<EmailBean>.
When saved in Firebase it's like :
"users" : {
"$userID" : {
"emails" : [
"0" : {
"type" : "first",
"address" : "google#google.com",
"private" : true
},
"1" : {
"type" : "second",
"address" : "firebase#firebase.com",
"private" : false"
}
],
"name" : "Mitch"
}
}
So is it possible to achieve something like this :
"users" : {
"$userID" : {
"emails" : [
"first" : {
"address" : "google#google.com",
"private" : true
},
"second" : {
"address" : "firebase#firebase.com",
"private" : false
}
],
"name" : "Mitch"
}
}
I would prefer to not having to save each address one at a time.
Maybe there's an annotation to tells Firebase to use this property as a key ?
Regards.
I recomend you using the code below:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference emailsRef = rootRef.child("users").child(userId).child("emails");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String type = ds.child("type").getValue(String.class);
ds.child("type").getRef().getParent().setValue(type);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
emailsRef.addListenerForSingleValueEvent(eventListener);
What have i tried with this code? So in order to achieve what you want, first of all we got the value of your type key. Then we get a step up in the tree and set the partent with the value of your type key for each particular node.
Having the value of type in stead of 0, 1 and so on, to get the work done, just remove the type key, from each node using removeValue() method directly on the reference.
I'm working using Firebase this my database is looking like
my database screenshot
{
"CookerInfo" : {
"org1mLyyJNXtiGo8NimxhWvpId42" : {
"about" : "Cooker since 2005",
"address" : "agamy - italy ",
"available" : "tuesday from 5 am to 9 pm",
"cookerDishes" : {
"-Kk3RgXiUEgpgjF1aAdc" : {
"foodName" : "mol5ia",
"foodUrl" : "https://firebasestorage.googleapis.com/v0/b/fir-auth- aa979.appspot.com/o/dishphoto%2F1494723249227.jpg?alt=media&token=0fc03b18-d310- 493a-b332-c1f3e4896567",
"price" : "8 $",
"timeToPrepared" : "10 min",
"weight" : "100 gm "
}
},
"name" : "chef.mohamed",
"phone" : "0192822228",
"url" : "https://firebasestorage.googleapis.com/v0/b/fir-auth-aa979.appspot.com/o/cookerPhoto%2F1494723157098.jpg?alt=media&token=19e4e376-0013-4410-bc04-0483aff09902"
},
"vuUscH2L7wgtj2N3rGWOOjgv23s2" : {
"about" : "cookgood",
"address" : "alexandria",
"available" : "sunday",
"cookerDishes" : {
"-Kk32fy0FO1vtZgm6AOK" : {
"foodName" : "chiken",
"foodUrl" : "https://firebasestorage.googleapis.com/v0/b/fir-auth- aa979.appspot.com/o/dishphoto%2F1494716692079.jpg?alt=media&token=a70ed96e-acbc-45c6-95b7-4811fd8e2e26",
"price" : "10$",
"timeToPrepared" : "10 min",
"weight" : "100gm"
},
"-Kk32mfQWiMRLFV2SMo7" : {
"foodName" : "rise",
"foodUrl" : "https://firebasestorage.googleapis.com/v0/b/fir-auth- aa979.appspot.com/o/dishphoto%2F1494716718899.jpg?alt=media&token=6b9007f5-c22e-4ed4-83aa-a80f45e5363f",
"price" : "8 $",
"timeToPrepared" : "8 min",
"weight" : "50 gm"
}
},
"name" : "sherbini",
"phone" : "01093812681",
"url" : "https://firebasestorage.googleapis.com/v0/b/fir-auth-aa979.appspot.com/o/cookerPhoto%2F1494716634787.jpg?alt=media&token=2ba72b6d-0af0-4235-bff5-4b706e91486f"
}
}
}
And I want to reach to cookerDishes for specific cooker only (1 cooker) to put his dishes in gridview, however I don't save the ID in model.
I tried something like that, but it didn't work.
Query queryRef=mDatabaseRef.orderByChild("name")
.equalTo(COOKERNAME);
DatabaseReference node =queryRef.getRef();
node.child("cookerDishes").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> children=dataSnapshot.getChildren();
for (DataSnapshot child : children){
FoodDish fooddish = new FoodDish();
String food_name =child.child("foodName").getValue(String.class);
fooddish.setFoodName(food_name);
foodList.add(fooddish);
}
gv.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I think you forgot to call notifyDataSetChanged() on your addapter
You don't need to call getRef() on the query. Instead you should attach the listener directly to the query:
Query queryRef=mDatabaseRef
.orderByChild("name")
.equalTo(COOKERNAME);
queryRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot cookerSnapshot : dataSnapshot.getChildren()){
DataSnapshot cookerDishes = cookerSnapshot.getChild("cookerDishes"));
for (DataSnapshot dishSnapshot: cookerDishes.getChildren()) {
FoodDish fooddish = new FoodDish();
String food_name =child.child("foodName").getValue(String.class);
fooddish.setFoodName(food_name);
foodList.add(fooddish);
}
I am populating a list of programs in a RecyclerView. Now i need to sort the programs by the time added. So i thought of adding a timestamp object to each program.
But i read that the PushID is also generated from a timestamp. So i tried to use the orderByKey(). But i can't figure out that how can i use the query with the userSnapshot?
CODE
public void FetchData() {
ProgramItemList.clear();
mRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
for (DataSnapshot programSnapshot : userSnapshot.getChildren()) {
program = programSnapshot.getValue(Program.class);
ProgramItem item = new ProgramItem();
String pushID = programSnapshot.getKey();
item.setID(pushID);
item.setName(program.getTitle());
ProgramItemList.add(item);
}
}
}
mAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
JSON
{
"subscriptions" : {
"han#gmail,com" : {
"-KDnhRwHjssOejrqyenP" : {
"category" : "Strength",
"goal" : "This workout can be done while on the phone!",
"length" : 1,
"title" : "Hello Workouts",
"weeks" : {
"week1" : [ "High Knees", "Jumping Jacks", "Burpees" ]
}
},
"-KDni3TN4NMyGXePyp92" : {
"category" : "Strength",
"goal" : "This workout can be done by a BABUJI",
"length" : 1,
"title" : "Indian Workouts",
"weeks" : {
"week1" : [ "Diamond Pushups", "Jackknives", "Pushups" ]
}
}
},
"obama#gmsil,com" : {
"-KDnfjROKeFAL9wccsxY" : {
"category" : "Mobility",
"goal" : "afternoon body weight workout",
"length" : 1,
"title" : "Afternoon HiiT",
"weeks" : {
"week1" : [ "High Knees", "Squats", "Lunges", "Diamond Push-ups", "Lying Triceps Lifts" ]
}
},
"-KDps90Dn6XtJc6Co00b" : {
"category" : "Strength",
"goal" : "goal",
"length" : 1,
"title" : "title",
"weeks" : {
"week1" : [ "Diamond Pushups", "Spiderman Push-up", "Wide Arm Push-ups", "Burpee Pushups" ]
}
}
}
}
}