Save and retrieve data from firebase database Android

Deadly 提交于 2021-02-11 12:50:32

问题


I'm working on a project where I have to do a custom "tour/trip" based on the locations the user chooses on the map. and every tour has a title, with the locations that he chose. say for example he made a tour(list) and called it 'Tour 1' and in this 'Tour 1' first he wants to go to the hotel, and then to KFC, and then to the beach.

I'm at the point where I made a list and gave it a title, but can't show the places that I planned to go in the activity, here is a screenshot of the activity activity example, and here is a screenshot of my realtime database.

realtime database example

so I want to show all the places that I planned to go, where it says 'Place 1' in the activity. here is my code.

userDatabase = FirebaseDatabase.getInstance().getReference("UsersToursList").child(userID);

userDatabase.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            tourList.clear();
            for (DataSnapshot tourSnapshot : snapshot.getChildren()) {
                Tour tour = tourSnapshot.getValue(Tour.class);
                tourList.add(tour);
            }
            MyToursListAdapter adapter = new MyToursListAdapter(MyToursActivity.this,tourList);
            list_view_tours.setAdapter(adapter);
        }
    });

here is the Adapter class

class MyToursListAdapter extends ArrayAdapter<Tour> {

private Activity mContext;
private List<Tour> TourList;

public MyToursListAdapter(Activity mContext, List <Tour>  TourList) {
    super(mContext,R.layout.tours_item_list,TourList);
    this.mContext = mContext;
    this.TourList = TourList;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    TextView tvTourTitle,tvPlace;
    LayoutInflater inflater = mContext.getLayoutInflater();
    View listItemView = inflater.inflate(R.layout.tours_item_list,null,true);
    tvTourTitle = listItemView.findViewById(R.id.tour_list_tv_TourTitle);
    tvPlace = listItemView.findViewById(R.id.tour_list_tv_place);

    Tour tour = TourList.get(position);

    tvTourTitle.setText(tour.getTourTitle());
    tvPlace.setText(tour.getPlace());

    return listItemView;
}

Tour class

class Tour {

String place;

public String getPlace() {
    return place;
}

I hope you understand.

EDIT: based on @Simran Sharma request I'll post the whole code that is realted to this issue.

First, Tour.java

class Tour {

String tourTitle;
String tourID;
String places;

public Tour(){

}
public Tour(String TourTitle,String TourID) {
    tourTitle = TourTitle;
    tourID = TourID;
}

public Tour(String TourTitle,String TourID,String Places) {
    tourTitle = TourTitle;
    tourID = TourID;
    places = Places;
}

public String getTourTitle() {
    return tourTitle;
}

public String getTourID() {
    return tourID;
}

public String getPlaces() {
    return places;
}

MyToursListAdapter.java, its actually the same as before, but i don't really know if i should use TextView or ListView. so let me know please because i think its an array not a normal string.

here is the code where i add(save) the place to the list and database:

Query query = myTourUserDatabase.orderByChild("tourTitle").equalTo(ListChosen);
            query.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    if(snapshot.exists()) {
                        for (DataSnapshot issue : snapshot.getChildren()) {
                            ListID = issue.getKey();
                            Log.d("mytag", "onClick: MapActivity Chosen list ref from spinner " + ListID);

                            TourListChosen_UserDB = FirebaseDatabase.getInstance().getReference("UsersToursList").child(userID).child(ListID);
                            Map<String, Object> Place = new HashMap<>();
                            Place.put("place",PlaceName);
                            //Tour tour = snapshot.getValue(Tour.class);
                            //places.add(tour);
                            TourListChosen_UserDB.setValue(Place);
                        }
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {

                }
            });

here is the code where i retreive the whole list (supposed to be with all the places that i added 'example KFC, Hotel ...' but its not working):

userDatabase.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            tourList.clear();
            for (DataSnapshot tourSnapshot : snapshot.getChildren()) {
                Tour tour = tourSnapshot.getValue(Tour.class);
                tourList.add(tour);
            }
            MyToursListAdapter adapter = new MyToursListAdapter(MyToursActivity.this,tourList);
            list_view_tours.setAdapter(adapter);
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

I think this is all the code what i got about this issue...


回答1:


Ok, so let's start with the Tour.java.

class Tour {

    // make these private
    private String tourTitle, tourID;

    // have this public
    ArrayList<Place> places;


    public Tour(){
        // required constructor
    }

    // main constructor
    public Tour(String tourTitle,String tourID) {
        this.tourTitle = tourTitle;
        this.tourID = tourID;
    }


    public String getTourTitle() {
        return tourTitle;
    }

    public String getTourID() {
        return tourID;
    }
}

Create another class Place.java

class Place {

    private String name;
    
    public Place() {}
    public Place(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

I am gonna use the below database reference throughout

dbRef = FirebaseDatabase.getInstance().getReference().child("userToursList").child(userId);

placesRef = dbRef.child(listId).child("places");

So when you want to add a tour do like below:

Tour tour = new Tour("Tour1", listId);
dbRef.child(listId).setValue(tour);

And when you want to add a new place, use the below code.

Place place = new Place("KFC");
placesRef.push().setValue(place);

Now in your activity declare the below fields:

ArrayList<Tour> tours = new ArrayList<>();
ArrayList<Place> places = new ArrayList<>();
MyToursListAdapter adapter = new Adapter(MyToursActivity.this, tours);
list_view_tours.setAdapter(adapter);

And when you want to retrieve the list of tours:

dbRef.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
                
                // check if the snapshot exists or not
                if (snapshot.exists()) {
                    // the snapshot exists, now retrieve the data
                    Tour tour = snapshot.getValue(Tour.class);

                    if (tour != null) {
                        // update the list with a new tour item
                        tours.add(tour);

                        // tell the adapter that the data has been updated
                        adapter.notifyDataSetChanged();
                    }
                }
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) { }
            @Override
            public void onChildRemoved(@NonNull DataSnapshot snapshot) { }
            @Override
            public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) { }
            @Override
            public void onCancelled(@NonNull DatabaseError error) { }
        });

And when you want to retrieve the list of places in a particular tour:

placesRef.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
                
                // check if the snapshot exists or not
                if (snapshot.exists()) {
                    // the snapshot exists, now retrieve the data
                    Place place = snapshot.getValue(Place.class);
                    
                    if (place != null) {
                        // update the list with a new tour item
                        places.add(place);
 
                        // you can update the places list in the Tour class as well like below
                        tour.places.add(place);
                        // inform adapter that the data has changed so changes can be seen
                        adapter.notifyDataSetChanged();
                    }
                }
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) { }
            @Override
            public void onChildRemoved(@NonNull DataSnapshot snapshot) { }
            @Override
            public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) { }
            @Override
            public void onCancelled(@NonNull DatabaseError error) { }
        });



回答2:


but can't show the places that I planned to go in the activity

You cannot do that because your "place" field in your "Tour" class cannot be mapped to a dynamic ID. It can be mapped to a property called "place", that can hold a specific value, but you cannot use a fixed property to map those pushed IDs. What you should do instead, is to change your database structure a little bit:

Firebase-root
  |
  --- UserToursList
        |
        --- On3I...Yq72
             |
             --- -MScb...BZUt
                  |
                  --- tourID: "-MScb...BZUt"
                  |
                  --- tourTitle: "Tour 1"
                  |
                  --- places
                       |
                       --- 0: "Jacob Samuel Hotel"
                       |
                       --- 1: "KFC"
                       |
                       --- 2: "Beach"

Where the "places" is considered an array. You can simply get that array as a List<String> in your Java code.

There is another option, in which you can use a Map<String, Object>, instead of an array, and your schema should look like this:

Firebase-root
  |
  --- UserToursList
        |
        --- On3I...Yq72
             |
             --- -MScb...BZUt
                  |
                  --- tourID: "-MScb...BZUt"
                  |
                  --- tourTitle: "Tour 1"
                  |
                  --- places
                       |
                       --- "Jacob Samuel Hotel": true
                       |
                       --- "KFC": true
                       |
                       --- "Beach": true

It's up to you to decide which one fits best.



来源:https://stackoverflow.com/questions/66031824/save-and-retrieve-data-from-firebase-database-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!