问题
I am implementing Firebase Recyclerview UI in my application. I have implemented a recyclerview adapter and it shows me following exception. Following is my adapter code :
FirebaseRecyclerAdapter<DataSnapshot, MyHolder> recyclerAdapter = new FirebaseRecyclerAdapter<DataSnapshot, MyHolder>(
DataSnapshot.class,
R.layout.row_slots,
MyHolder.class,
databaseReference.child("slots").child(uid).child(dayOfWeek).child("time")
) {
@Override
protected void populateViewHolder(MyHolder viewHolder, DataSnapshot model, int position) {
System.out.println("Key : "+model.getKey());
}
};
It is showing following exception :
How can I get a snapshot value using FirebaseRecyclerAdapter?
回答1:
firebaser (and author of the FirebaseUI adapters) here
Lots of good answers already. I'd indeed typically recommend creating a Java class that represents your data objects.
But if you're intent on using a DataSnapshot
, you can override FirebaseRecyclerAdapter.parseSnapshot
to handle the "conversion":
@Override
protected ChatMessage parseSnapshot(DataSnapshot snapshot) {
return snapshot;
}
回答2:
The problem is DataSnapShot
is missing a no Argument Constructor so you can not use it directly like this.
Use some other model class instead.
Like this :
Create your own model called FriendlyMessage
:
public class FriendlyMessage {
private String text;
private String name;
// Created constructor with no Arguments
public FriendlyMessage() {
}
public FriendlyMessage(String text, String name) {
this.text = text;
this.name = name;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Most important thing we have created constructor with no Arguments which was missing in
DataSnapShot
NOTE : The above model class is just an example for you as you are new in firebase. You can have your own model class with your own type of parameters and all.
The use it like this for your Firebase Recyclerview :
FirebaseRecyclerAdapter mFirebaseAdapter = new FirebaseRecyclerAdapter<FriendlyMessage, MyHolder>(
FriendlyMessage.class,
R.layout.row_slots,
MyHolder.class,
databaseReference.child("slots").child(uid).child(dayOfWeek).child("time")) {
@Override
protected void populateViewHolder(MyHolder viewHolder, FriendlyMessage friendlyMessage, int position)
{
}
};
EDIT :
It also matter how you are pushing the data on Database. Do it directly with your model class.
For example for above model FriendlyMessage
push it like this :
FriendlyMessage friendlyMessage = new FriendlyMessage("message", "Username");
databaseReference.child(MESSAGES_CHILD).push().setValue(friendlyMessage);
Here your child()
will be somewhat different from my implementation it is just an example.
For Listening to a particular DataSnapShot :
databaseReference.child("users").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
//The PUSH ID OP WANTED
System.out.println("Push Id ---"+postSnapshot.getKey());
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
})
Explaining the above listener. It will give you the
DataSnapShot
Object for your every user who is falling inside your child "users". You can access Push id bygetKey()
method.
回答3:
When initializing your recyclerAdapter
, your passing a DataSnapshot.class
as your modelClass
, wherein a DataSnapshot doesn't really have a Constructor with no parameters which I think is causing the error, also I think that makes a DataSnapshot
an invalid modelClass
.
As stated in the FirebaseRecyclerViewAdapter for the modelClass
:
modelClass - Firebase will marshall the data at a location into an instance of a class that you provide
You should define your own modelClass
by creating an object that suites your needs. There's a simple example on the FirebaseRecyclerViewAdapter
link that you can check out. Cheers!
EDIT:
As per the comments, I suggested to have your own modelClass object have a DataSnapshot
as a parameter. For a simple example of what I'm saying, refer below.
public class ModelClass {
String sampleString;
ModelClass() {
}
ModelClass(DataSnapshot dataSnapshot) {
// Do what you need from the dataSnapshot here
sampleString = dataSnapshot.child("").toString();
}
}
I think from the example above, you would get what I mean. BUT, I'm not sure if this is recommended nor if it's even acceptable. I haven't tried this out before so I'm also not sure if it'll work.
Since this concern is actually different from the one posted. I suggest posting a different one if ever it doesn't work. Happy Coding. Cheers!
来源:https://stackoverflow.com/questions/38144597/datasnapshot-is-missing-a-constructor-with-no-arguments