简体   繁体   中英

Error while retrieving data from firebase in recyclerView

I understand a lot of people have asked the same question but I have tried a lot of methods but this still isn't working.

I am making an app where users can write notes. So once the notes are written and entered into the firebase, I want to retrieve them in a card view having the title and time of the note.

But when i open the open the posts, the app crashes and gives me error and the recyclerView is empty...

I have already tried:

  1. setting height to wrap_content
  2. adding notifysetDataChange
  3. adding startListening

Here is my code:

Posts Activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_post);

    mNotesList = (RecyclerView) findViewById(R.id.notes_list);

    gridLayoutManager = new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false);

    mNotesList.setHasFixedSize(true);
    mNotesList.setLayoutManager(gridLayoutManager);
    mNotesList.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true));

    fAuth = FirebaseAuth.getInstance();
    fNotesDatabase = FirebaseDatabase.getInstance().getReference().child("Notes");
    CurrentUserID = fAuth.getCurrentUser().getUid();

    loadData();
}

private void loadData() {

    Query myPostsQuery = fNotesDatabase.orderByChild("uid")
    .startAt(CurrentUserID).endAt(CurrentUserID + "\uf8ff");

    FirebaseRecyclerOptions<NoteModelActivity> options =
            new FirebaseRecyclerOptions.Builder<NoteModelActivity>()
                    .setQuery(myPostsQuery , NoteModelActivity.class)
                    .build();

    FirebaseRecyclerAdapter<NoteModelActivity, NoteViewHolderActivity> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<NoteModelActivity, NoteViewHolderActivity>(options) {
        @NonNull
        @Override
        public NoteViewHolderActivity onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_note_layout, parent, false);
            NoteViewHolderActivity viewHolder = new NoteViewHolderActivity(view);
            return viewHolder;
        }

        @Override
        protected void onBindViewHolder(@NonNull final NoteViewHolderActivity holder, int position, @NonNull NoteModelActivity model) {

            final String noteId = getRef(position).getKey();

            fNotesDatabase.child(noteId).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    if (dataSnapshot.hasChild("title") && dataSnapshot.hasChild("timestamp")) {
                        String title = dataSnapshot.child("title").getValue().toString();
                        String timestamp = dataSnapshot.child("timestamp").getValue().toString();

                        holder.setNoteTitle(title);

                        GetTimeAgo getTimeAgo = new GetTimeAgo();
                        holder.setNoteTime(getTimeAgo.getTimeAgo(Long.parseLong(timestamp), getApplicationContext()));

                        holder.noteCard.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                Intent intent = new Intent(PostActivity.this, NewNoteActivity.class);
                                intent.putExtra("noteId", noteId);
                                startActivity(intent);
                            }
                        });
                    }

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });


        }
    };
    mNotesList.setAdapter(firebaseRecyclerAdapter);
    firebaseRecyclerAdapter.startListening();
}

private int dpToPx(int dp) {
    Resources r = getResources();
    return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}

My model class:

public class NoteModelActivity  {

    public String noteTitle;
    public String noteTime;
    public String uid;

    public NoteModelActivity() {}

    public NoteModelActivity(String noteTitle, String noteTime, String uid) {
        this.noteTitle = noteTitle;
        this.noteTime = noteTime;
        this.uid = uid;
    }

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public String getNoteTitle() {
        return noteTitle;
    }

    public void setNoteTitle(String noteTitle) {
        this.noteTitle = noteTitle;
    }

    public String getNoteTime() {
        return noteTime;
    }

    public void setNoteTime(String noteTime) {
        this.noteTime = noteTime;
    }
}

My logcat:

com.google.firebase.database.DatabaseException: Failed to convert value of type java.lang.Long to String
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertString(CustomClassMapper.java:425)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:216)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(CustomClassMapper.java:178)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.access$100(CustomClassMapper.java:47)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:592)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:562)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:432)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:231)
    at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:79)
    at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
    at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:29)
    at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:15)
    at com.firebase.ui.common.BaseCachingSnapshotParser.parseSnapshot(BaseCachingSnapshotParser.java:36)
    at com.firebase.ui.common.BaseObservableSnapshotArray.get(BaseObservableSnapshotArray.java:52)
    at com.firebase.ui.database.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:109)
    at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:149)
    at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
    at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
    at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
    at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
    at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
    at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
    at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1897)
    at androidx.recyclerview.widget.RecyclerView$1.run(RecyclerView.java:414)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1147)
    at android.view.Choreographer.doCallbacks(Choreographer.java:958)
    at android.view.Choreographer.doFrame(Choreographer.java:881)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1133)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:226)
    at android.app.ActivityThread.main(ActivityThread.java:7224)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:500)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:913)

I/Process: Sending signal. PID: 9172 SIG: 9

My firebase database:

数据库

Issue solved...

I changed the timestamp to String while entering it into the database, with that all the problems are gone...

Thanks a lot to all of you who answered... I'm utterly grateful.

Try replacing

String timestamp = dataSnapshot.child("timestamp").getValue().toString();

with this

String timestamp = ""+dataSnapshot.child("timestamp").getValue();

Try changing

String timestamp = dataSnapshot.child("timestamp").getValue().toString();

to

String timestamp = String.valueOf(dataSnapshot.child("timestamp").getValue());

The crash log clearly indicates that, there was a problem converting the long data to a string. I do not see any problem in your code yet though, however, I assume that getTimeAgo.getTimeAgo function is the culprit here. You might want to set a debug pointer in your getTimeAgo function and check if that is being returned correctly.

I have one more recommendation actually. It looks like you are converting the long value that you get from the database and then parse the long value again while you are passing it to the getTimeAgo function. I think that is redundant and could be avoided.

You could modify the onDataChange portion as follows.

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    if (dataSnapshot.hasChild("title") && dataSnapshot.hasChild("timestamp")) {
        String title = dataSnapshot.child("title").getValue().toString();
        Long timestamp = dataSnapshot.child("timestamp").getValue();

        holder.setNoteTitle(title);

        GetTimeAgo getTimeAgo = new GetTimeAgo();
        holder.setNoteTime(getTimeAgo.getTimeAgo(timestamp, getApplicationContext()));

        holder.noteCard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(PostActivity.this, NewNoteActivity.class);
                intent.putExtra("noteId", noteId);
                startActivity(intent);
            }
        });
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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