繁体   English   中英

从 firebase 数据库 Android 保存和检索数据

[英]Save and retrieve data from firebase database Android

我正在做一个项目,我必须根据用户在 map 上选择的位置进行自定义“旅行/旅行”。 每次旅行都有一个标题,以及他选择的地点。 例如,他做了一个旅行(列表)并将其称为“Tour 1”,在这个“Tour 1”中,他首先想要 go 到酒店,然后到肯德基,然后到海滩。

我在做一个列表并给它一个标题的地步,但是在活动中无法显示我计划到 go 的地方,这里是活动活动示例的截图,这里是我的截图实时数据库。

实时数据库示例

所以我想展示我计划到 go 的所有地方,它在活动中显示“Place 1”。 这是我的代码。

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);
        }
    });

这是适配器 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;
}

游class

class Tour {

String place;

public String getPlace() {
    return place;
}

我希望你明白。

编辑:根据@Simran Sharma 的请求,我将发布与此问题相关的整个代码。

一、 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 ,它实际上和以前一样,但我真的不知道我应该使用 TextView 还是 ListView。 所以请告诉我,因为我认为它是一个数组而不是一个普通的字符串。

这是我将位置添加(保存)到列表和数据库的代码:

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) {

                }
            });

这是我检索整个列表的代码(应该是我添加的所有地方'例如肯德基,酒店......'但它不起作用):

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) {

        }
    });

我认为这就是我得到的关于这个问题的所有代码......

但无法在活动中显示我计划到 go 的地方

您不能这样做,因为您的“Tour” class 中的“place”字段无法映射到动态 ID。 它可以映射到一个名为“place”的属性,它可以保存一个特定的值,但是你不能使用一个固定的属性来 map 那些推送的 ID。 你应该做的是稍微改变你的数据库结构:

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

“地点”被认为是一个数组。 您可以在 Java 代码中简单地将该数组作为List<String>获取。

还有另一种选择,您可以在其中使用 Map<String, Object>,而不是数组,并且您的架构应如下所示:

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

由您决定哪一个最适合。

好的,让我们从 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;
    }
}

创建另一个 class Place.java

class Place {

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

    public String getName() {
        return name;
    }
}

我将在整个过程中使用以下数据库参考

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

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

因此,当您想添加游览时,请执行以下操作:

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

当您想添加新地点时,请使用以下代码。

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

现在在您的活动中声明以下字段:

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

当您要检索旅行列表时:

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) { }
        });

当您想要检索特定游览中的地点列表时:

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) { }
        });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM