【问题标题】:Android - Cannot retrieve data from FirebaseAndroid - 无法从 Firebase 检索数据
【发布时间】:2018-04-06 06:02:21
【问题描述】:

我正在两个标记之间绘制一条路线,我想保存该路线。为此,我将包含 lat 和 lng 的 ArrayList 保存在 Firebase 数据库中。但我在检索航点时遇到问题。我是这样插入的:

String routeId = database.push().getKey();
database.child(sharedPreferences.getString("school", null)).child("routes").child(routeId).setValue(points);
SharedPreferences.Editor editor = getActivity().getSharedPreferences("sh", MODE_PRIVATE).edit();
            editor.putString("key", routeId);
            editor.commit();

sharedPreferences 字符串“school”是学校的名称,routeIdpush() 键,points 是航点的 ArrayList

我的数据库:

我的 POJO 课程:

public static class Route {

    private ArrayList<Location> locations;

    public Route() {
    }

    public ArrayList<Location> getLocations() {
        return locations;
    }

    public void setLocations(ArrayList<Location> locations) {
        this.locations = locations;
    }
}


public static class Location {
    private Double latitude;
    private Double longitude;

    public Location() {
    }

    public Double getLatitude() {
        return latitude;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public Double getLongitude() {
        return longitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }
}

路点检索:

  points = new ArrayList();
    userRef.child(sharedPreferences.getString("school", null)).child("routes").child(sh.getString("key",null)).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Route route = dataSnapshot.getValue(Route.class);
            for (Location location : route.getLocations()) {
                double lat = location.getLatitude();
                double lng = location.getLongitude();
                position = new LatLng(lat, lng);
                points.add(position);
            }
        }

但是我得到一个数据库异常:

DatabaseException:无法将 java.util.ArrayList 类型的对象转换为 packagename 类型

我不知道为什么。

【问题讨论】:

标签: android firebase firebase-realtime-database


【解决方案1】:

试试这个

    final HashMap<Integer,HashMap<String,Double>> positions = new HashMap<>();
    userRef.child(sharedPreferences.getString("school", null)).child("routes").child(sh.getString("key",null)).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            int i=0;
            for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
                HashMap<String,Double> position = new HashMap<String, Double>();
                position.put("lat",Double.parseDouble(postSnapshot.child("latitude").getValue().toString()));
                position.put("lng",Double.parseDouble(postSnapshot.child("longitude").getValue().toString()));
                positions.put(i++,position);
            }

        }

您可以访问存储在positions 变量中的值

 positions.get(index).get("lat");
 positions.get(index).get("lng");

【讨论】:

  • NumberFormatException:对于输入字符串:“DataSnapshot { key = lat, value = null
  • 我也试过这个。我得到了和以前一样的错误:DatabaseException: Can't convert object of type java.util.ArrayList to type packagename
  • @JDoe 等等我知道错误是什么。我会更新代码
  • 我现在收到此错误:NumberFormatException: For input string: "DataSnapshot { key = latitude, value = 55.3975 }
【解决方案2】:

您的代码几乎是正确的,但我认为是数据的保存让它失望了。当您从数据库加载数据时,您会将数据编组到 Route 实例中:

Route route = dataSnapshot.getValue(Route.class);

这将期望每个子节点下的 locations 节点与您的 POJO 类中的 setLocations(ArrayList&lt;Location&gt;) 匹配。相反,它检索的数据直接是ArrayList

保存位置列表时,您需要安排结构,使位置列表存储在$schoolName/routes/$routeId/locations 下:

因此,在保存路线点数据时,您需要:

database.child(schoolName).child("routes").child(routeId).child("locations").setValue(points);

想到这一点的一个简单方法是:如果 Route 也有一个名称字段 (setName(String)),那么数据库中的 $schoolName/routes/$routeId/name 也可能与 locations 值位于同一位置。

或者,当保存到数据库时,您可以将 points 变量转换为 Route 实例,然后将其直接推送到 $schoolName/routes/$routeId,这将确保它被正确存储。

【讨论】:

  • 感谢您的回答。如果我采用您的第二个解决方案:points 变量是一个数组列表。有没有一种简单的方法可以将其转换为Route 实例?
  • points 变量是否已经是 ArrayList&lt;Location&gt;?你可以只做Route route = new Route(); route.setLocations(points); 或者为它创建一个构造函数。
  • 快速提问:在onDataChange 中运行的代码,会只采用最后添加的航点吗?
  • 它将遍历每个被推送到routes 节点的子节点。如果您只想要最新的,则需要使用对sort and filter 的查询:您可以将orderByKey()limitToLast(1) 附加到您的引用中,以仅获取最新的。
  • 好吧,我的想法正好相反,这样我就可以在“路线”节点中绘制与子节点一样多的折线。我会试着弄清楚。谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
相关资源
最近更新 更多