Search code examples
androidfirebaseandroid-recyclerviewfirebase-realtime-databasefirebaseui

Unable to populate recycler viiew from Firebase DB


Though this question was answered a few times, any of the answers were not able to solve my problem.

I have a firebase DB which only has two key-value pairs. Below is the json.

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

The following is my code to get data from firebase DB

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

This is the simple code without any recyclerview as suggested by Frank. The code is working fine. No Jackson errors

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

        }
    });
}

This following is my 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;
}
}

The issue with the code is that the Jackson is unable to deserialize the data sent by Firebase when I am using the POJO. When I use a simple String class instead of the Route POJO, the data being perfectly written into the recycler view item. Below is the error log

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) 

I have flushed the data from Firebase checking to ensure that the String names in POJO and Firebase DB match multiple times. I understand I'm missing something related to the POJO but not able to figure it out.

But the error still exists with recycler view !!!


Solution

  • The silliest mistake was that I forgot that a recycler view takes a list of properties and I had multiple properties (stop and time) to display in one row. So i just need to fetch the routeA and give it to firebasui to display. I went into deeper level while getting the data upto routeA and the firebaseui was not able to recognize the properties. Only one level query upto route is enough to display the stop and time properties in single row.

    Wrote it as a separate answer so that it helps the guys like me who are ignorant of little but important things. This concept is also a part of the answer posted by @Frank van Puffelen to one of the similar.