我正在尝试从Firebase子节点获取数据。但它会引发Can't convert object of type java.lang.String to type uk.co.stableweb.geethika.model.DailyVerse
异常。
这是我的Firebase数据库的结构。
这是代码。我正在使用Android Firebase新版documentation。
mRef = FirebaseDatabase.getInstance().getReference().child("daily_verse");
mRef.keepSynced(true);
ChildEventListener childEventListener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d("Child Event,Verse", dataSnapshot.getKey());
dailyVerse = dataSnapshot.getValue(DailyVerse.class);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d("Child Event,Verse", "onChildChanged:" + dataSnapshot.getKey());
dailyVerse = dataSnapshot.getValue(DailyVerse.class);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w("Firebase", "onCancelled", databaseError.toException());
Toast.makeText(context, "Failed to load verse",
Toast.LENGTH_SHORT).show();
}
};
mRef.addChildEventListener(childEventListener);
和Model class。
public class DailyVerse {
private String verse_title;
private String verse_content;
public String getVerseTitle() {
return verse_title;
}
public void setVerseTitle(String verse_title) {
this.verse_title = verse_title;
}
public String getVerseContent() {
return verse_content;
}
public void setVerseContent(String verse_content) {
this.verse_content = verse_content;
}
}
和LogCat。
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type uk.co.stableweb.geethika.model.DailyVerse
at com.google.android.gms.internal.zzalq.zzd(Unknown Source)
at com.google.android.gms.internal.zzalq.zzb(Unknown Source)
at com.google.android.gms.internal.zzalq.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at uk.co.stableweb.geethika.VerseActivityFragment$1.onChildAdded(VerseActivityFragment.java:63)
at com.google.android.gms.internal.zzahh.zza(Unknown Source)
at com.google.android.gms.internal.zzajh.zzctc(Unknown Source)
at com.google.android.gms.internal.zzajk$1.run(Unknown Source)
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:5461)
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)
但是如果我按如下方式更改数据库引用。并获取dataSnapshot值,它会抓取数据。
mRef = FirebaseDatabase.getInstance().getReference("daily_verse");
testVal = (String) dataSnapshot.getValue();
Log.d("TEST", testVal);
V/FA: Activity resumed, time: 278033062
D/Child Event,Verse added: verse_content
D/TEST: විශ්වාසකමේ මාර්ගය තෝරා ගතිමි. ඔබගේ විනිශ්චයන් මා ඉදිරියෙහි තබා ගතිමි.
D/Child Event,Verse added: verse_title
D/TEST: ගීතාවලිය 119:30
我认为可以使用HashMap获取这些值。但有评论说不再推荐。
答案 0 :(得分:5)
请注意JSON中属性的名称以及Java代码中的字段/ getter。如果它们不匹配,Firebase客户端将无法匹配它们之间的值。
您的JSON有verse_title
和verse_content
,因此您的Java类必须 :
public class DailyVerse {
public String verse_title;
public String verse_content;
}
或:
public class DailyVerse {
private String verse_title;
private String verse_content;
public String getVerse_title() {
return verse_title;
}
public void setVerse_title(String verse_title) {
this.verse_title = verse_title;
}
public String getVerse_content() {
return verse_content;
}
public void setVerse_content(String verse_content) {
this.verse_content = verse_content;
}
}
自Firebase Android SDK 9.2起,您还可以注释Java代码以映射到正确的JSON属性。因此,获得正确映射的第三种方法是:
public class DailyVerse {
private String verse_title;
private String verse_content;
@PropertyName("verse_title")
public String getVerseTitle() {
return verse_title;
}
public void setVerseTitle(String verse_title) {
this.verse_title = verse_title;
}
@PropertyName("verse_content")
public String getVerseContent() {
return verse_content;
}
public void setVerseContent(String verse_content) {
this.verse_content = verse_content;
}
}
我没有尝试过这个最新的版本,所以如果答案上有拼写错误,请告诉我。
答案 1 :(得分:3)
通过这种方法
mRef.addChildEventListener(childEventListener);
您订阅了
.child("daily_verse");
孩子。 daily_verse有两个孩子:verse_content和verse_title。这些孩子的类型是String。因此,您可以在onChildAdd侦听器中获得两个String数据快照。
<强>更新强> 尝试这样的事情:
mRef = FirebaseDatabase.getInstance().getReference();
mRef.keepSynced(true);
ChildEventListener childEventListener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d("Child Event,Verse", dataSnapshot.getKey());
if ("daily_verse".equal(dataSnapshot().getKey){
dailyVerse = dataSnapshot.getValue(DailyVerse.class);
Log.d("TEST","Object: "+dailyVerse);
if (dailyVerse!=null){
Log.d("TEST","values: "+dailyVerse.verse_title+", "+dailyVerse.verse_content);
}
}
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d("Child Event,Verse", "onChildChanged:" + dataSnapshot.getKey());
if ("daily_verse".equal(dataSnapshot().getKey){
dailyVerse = dataSnapshot.getValue(DailyVerse.class);
Log.d("TEST","Changed object: "+dailyVerse);
if (dailyVerse!=null){
Log.d("TEST","Changed values: "+dailyVerse.verse_title+", "+dailyVerse.verse_content);
}
}
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w("Firebase", "onCancelled", databaseError.toException());
Toast.makeText(context, "Failed to load verse",
Toast.LENGTH_SHORT).show();
}
};
mRef.addChildEventListener(childEventListener);
您应该订阅来自父对象的事件,并在事件监听器处检查密钥。
答案 2 :(得分:1)
DataRef = FirebaseDatabase.getInstance().getReference().child("Users");
DataRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String acctname = (String)dataSnapshot.child("Name").getValue();
String acctmail = (String)dataSnapshot.child("Email").getValue();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
答案 3 :(得分:1)
使用firebase模型类时,您必须包含一个空构造函数以供firebase使用。
尝试将其添加为
public class DailyVerse {
public DailyVerse(){
}
}
答案 4 :(得分:0)
ArrayList<EventsResponse> usersEventsList = new ArrayList<>();
dummyIdsArrayList = new ArrayList<>();
Iterator<DataSnapshot> eventsIterator = dataSnapshot.getChildren().iterator();
while (eventsIterator.hasNext()) {
DataSnapshot eventsSnapShot = eventsIterator.next();
EventsResponse eventsResponse = new EventsResponse();
eventsResponse.setEventName(eventsSnapShot.getKey());
Iterator<DataSnapshot> eventChildIterator = eventsSnapShot.getChildren().iterator();
while (eventChildIterator.hasNext()) {
DataSnapshot eventchildSnapshot = eventChildIterator.next();
if (eventchildSnapshot.getKey().equals("is_recursive")) {
eventsResponse.setRecursive((Boolean) eventchildSnapshot.getValue());
} else if (eventchildSnapshot.getKey().equals("is_notif")) {
eventsResponse.setNotif((Boolean) eventchildSnapshot.getValue());
} else if (eventchildSnapshot.getKey().equals("is_editable")) {
eventsResponse.setEditable((Boolean) eventchildSnapshot.getValue());
} else if (eventchildSnapshot.getKey().equals("is_visible")) {
eventsResponse.setVisible((Boolean) eventchildSnapshot.getValue());
} else if (eventchildSnapshot.getKey().equals("name")) {
eventsResponse.setName(eventchildSnapshot.getValue().toString());
} else if (eventchildSnapshot.getKey().equals("date")) {
Iterator<DataSnapshot> eventChildDateIterator = eventchildSnapshot.getChildren().iterator();
while (eventChildDateIterator.hasNext()) {
DataSnapshot eventchildDateSnapshot = eventChildDateIterator.next();
if (eventchildDateSnapshot.getKey().equals("day")) {
eventsResponse.setDay(eventchildDateSnapshot.getValue().toString());
} else if (eventchildDateSnapshot.getKey().equals("month")) {
eventsResponse.setMonth(eventchildDateSnapshot.getValue().toString());
} else if (eventchildDateSnapshot.getKey().equals("year")) {
eventsResponse.setYear(eventchildDateSnapshot.getValue().toString());
}
}
} else {
eventsResponse.setNotif(true);
eventsResponse.setVisible(false);
}
}
如果您无法获取数据,则可以获取该格式的数据。