【问题标题】:Unable to populate recycler viiew from Firebase DB无法从 Firebase DB 填充回收站视图
【发布时间】:2016-05-06 17:29:31
【问题描述】:

虽然这个问题被回答了几次,但任何一个答案都无法解决我的问题。

我有一个只有两个键值对的 firebase 数据库。下面是json。

{
   "route" : {
   "routeA" : {
   "stop" : "Street 1",
   "time" : "11:00 PM"
  }
 }
}

以下是我从 firebase 数据库中获取数据的代码

  recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    rootRef = new Firebase("https://listrecycler.firebaseio.com/route/");
}

@Override
protected void onStart() {
    super.onStart();
    itemsRef = rootRef.child("route B");
    Toast.makeText(MainActivity.this, "crossed itemRef", Toast.LENGTH_SHORT).show();
    firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Route, RouteViewHolder>(Route.class, android.R.layout.two_line_list_item, RouteViewHolder.class, itemsRef) {
        @Override
        public void populateViewHolder(RouteViewHolder routeViewHolder, Route route, int i) {
            Toast.makeText(MainActivity.this, "reached populate view holder", Toast.LENGTH_SHORT).show();
            Log.d(TAG, "populateViewHolder: " + route);
            routeViewHolder.place.setText(route.getStop());
            routeViewHolder.time.setText(route.getTime());
        }
    };
    recyclerView.setAdapter(firebaseRecyclerAdapter);

}

public static class RouteViewHolder extends RecyclerView.ViewHolder {

    TextView place;
    TextView time;

    public RouteViewHolder(View itemView) {
        super(itemView);
        place = (TextView) itemView.findViewById(android.R.id.text1);
        time = (TextView) itemView.findViewById(android.R.id.text2);
    }
}

这是 Frank 建议的没有任何 recyclerview 的简单代码。代码工作正常。没有杰克逊错误

 rootRef = new Firebase("https://listrecycler.firebaseio.com/route");

}

@Override
protected void onStart() {
    super.onStart();
    itemsRef = rootRef.child("routeA");

    itemsRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Route routeDetails = dataSnapshot.getValue(Route.class);
            String stop = routeDetails.getStop();
            String time = routeDetails.getTime();
            Toast.makeText(MainActivity.this, "Stop Name:"+ stop+"Time:"+time, Toast.LENGTH_SHORT).show();
            Log.d(TAG, "onDataChange: "+dataSnapshot);
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });
}

以下是我的 POJO

public class Route {
public String stop;
public String time;

public Route() {
}

public Route(String stop, String time) {
    this.stop = stop;
    this.time = time;
}

public String getStop() {
    return stop;
}

public void setStop(String stop) {
    this.stop = stop;
}

public String getTime() {
    return time;
}

public void setTime(String time) {
    this.time = time;
}
}

代码的问题是当我使用 POJO 时,Jackson 无法反序列化 Firebase 发送的数据。当我使用简单的 String 类而不是 Route POJO 时,数据被完美地写入到回收器视图项中。以下是错误日志

05-06 22:38:03.724 30051-30051/abc.com.example.vijsu.listrecyclerfirebase E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                        Process: abc.com.example.vijsu.listrecyclerfirebase, PID: 30051
                                                                                        com.firebase.client.FirebaseException: Failed to bounce to type
                                                                                            at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:183)
                                                                                            at com.firebase.ui.FirebaseRecyclerAdapter.parseSnapshot(FirebaseRecyclerAdapter.java:161)
                                                                                            at com.firebase.ui.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:150)
                                                                                            at com.firebase.ui.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:190)
                                                                                            at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5465)
                                                                                            at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5498)
                                                                                            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4735)
                                                                                            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4611)
                                                                                            at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1988)
                                                                                            at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1384)
                                                                                            at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1347)
                                                                                            at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:574)
                                                                                            at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3026)
                                                                                            at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2903)
                                                                                            at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1457)
                                                                                            at android.support.v7.widget.RecyclerView.access$400(RecyclerView.java:147)
                                                                                            at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:285)
                                                                                            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
                                                                                            at android.view.Choreographer.doCallbacks(Choreographer.java:670)
                                                                                            at android.view.Choreographer.doFrame(Choreographer.java:603)
                                                                                            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
                                                                                            at android.os.Handler.handleCallback(Handler.java:739)
                                                                                            at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                            at android.os.Looper.loop(Looper.java:148)
                                                                                            at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                                         Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class abc.com.example.vijsu.listrecyclerfirebase.Route] from String value; no single-String constructor/factory method
                                                                                            at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator._createFromStringFallbacks(StdValueInstantiator.java:428)
                                                                                            at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:299)
                                                                                            at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1056)
                                                                                            at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:136)
                                                                                            at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:123)
                                                                                            at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
                                                                                            at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
                                                                                            at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:181)
                                                                                            at com.firebase.ui.FirebaseRecyclerAdapter.parseSnapshot(FirebaseRecyclerAdapter.java:161) 
                                                                                            at com.firebase.ui.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:150) 
                                                                                            at com.firebase.ui.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:190) 
                                                                                            at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5465) 
                                                                                            at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5498) 
                                                                                            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4735) 
                                                                                            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4611) 
                                                                                            at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1988) 
                                                                                            at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1384) 
                                                                                            at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1347) 
                                                                                            at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:574) 
                                                                                            at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3026) 
                                                                                            at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2903) 
                                                                                            at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1457) 
                                                                                            at android.support.v7.widget.RecyclerView.access$400(RecyclerView.java:147) 
                                                                                            at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:285) 
                                                                                            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) 
                                                                                            at android.view.Choreographer.doCallbacks(Choreographer.java:670) 
                                                                                            at android.view.Choreographer.doFrame(Choreographer.java:603) 
                                                                                            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) 
                                                                                            at android.os.Handler.handleCallback(Handler.java:739) 
                                                                                            at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                            at android.os.Looper.loop(Looper.java:148) 
                                                                                            at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                                            at java.lang.reflect.Method.invoke(Native Method) 
                                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

我已从 Firebase 检查中刷新数据,以确保 POJO 和 Firebase DB 中的字符串名称匹配多次。我知道我缺少与 POJO 相关的内容,但无法弄清楚。

但是recycler view依然存在这个错误!!!

【问题讨论】:

  • 我们最近收到了一些此异常的案例。例如。 stackoverflow.com/questions/36231398。如果这不是原因,您能否将 JSON 的图片替换为实际的 JSON,您可以通过单击 Firebase 仪表板中的“导出”按钮轻松获得。另外:你能把问题隔离在一段不需要RecyclerView的代码中吗?我很确定您可以使用单个 ref.getValue(Route.class) 复制它,这样可以更轻松地为您提供帮助。
  • @FrankvanPuffelen 按照您的要求附加了 JSON。没有回收站视图的简单代码工作得很好。但我需要在我的代码中查看回收站。谢谢。

标签: android firebase android-recyclerview firebase-realtime-database firebaseui


【解决方案1】:

错误中提到了这一点

无法实例化类型的值...路由...没有单字符串构造函数/工厂方法

所以你可能想添加一个

public class Route {

    public String stop;
    public String time;

    public Route() {}

    public Route(String routeJSON) { 
        // TODO: Parse out JSON object
        // call setters...
    }

    public Route(String stop, String time) {
        this.stop = stop;
        this.time = time;
    }

【讨论】:

  • cricket_007 我刚刚从参数化构造函数中删除了第二个参数,一切正常,使其成为单个字符串构造函数。但问题是我需要参数化构造函数将数据推送到 firebase 数据库。公共路线(字符串停止){ this.stop = stop; }
  • 我发现的另一件事是,无论单个字符串构造中存在哪个属性,只有该值是从 JSON 中提取的。另一个值返回 null。
  • 那是因为你必须设置 both 字符串...你得到一个包含两个值的 JSON 字符串。这就是我所说的routeJSON 和“呼叫设置器”的意思。您需要使用 Jackson 将该字符串转换为 JSONObject
【解决方案2】:

最愚蠢的错误是我忘记了回收站视图需要一个属性列表,并且我有多个属性(停止和时间)要显示在一行中。所以我只需要获取 routeA 并将其交给 firebasui 显示。我在将数据上传到 routeA 时进入了更深层次,而 firebaseui 无法识别这些属性。只有到 route 的一级查询就足以在单行中显示 stoptime 属性。

把它写成一个单独的答案,这样它可以帮助像我这样对小而重要的事情一无所知的人。这个概念也是@Frank van Puffelen 对类似问题的回答的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-10
    • 2021-09-29
    • 1970-01-01
    • 2019-04-18
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多