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:
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.