我正在使用Firebase UI回收适配器从Firestore读取数据
FirestoreRecyclerOptions<Transaction> options =
new FirestoreRecyclerOptions.Builder<Transaction>()
.setQuery(mQuery, Transaction.class)
.setLifecycleOwner(this)
.build();
mAdapter = new TransactionAdapter(options, this, getActivity()) {
@Override
public void onDataChanged() {
// Show/hide content if the query returns empty.
if (getItemCount() == 0) {
mRestaurantsRecycler.setVisibility(View.GONE);
mEmptyView.setVisibility(View.VISIBLE);
} else {
mRestaurantsRecycler.setVisibility(View.VISIBLE);
mEmptyView.setVisibility(View.GONE);
}
}
@Override
public void onError(FirebaseFirestoreException e) {
Log.e("Error", ", not initializing RecyclerView",e);
}
};
Log.w("Test", "No6 query, not initializing RecyclerView");
mRestaurantsRecycler.setLayoutManager(new LinearLayoutManager(getActivity()));
mRestaurantsRecycler.setAdapter(mAdapter);
对于Firestore中某些损坏的字段,我的状态已变得异常
java.lang.RuntimeException: Could not deserialize object. Failed to convert a value of type java.lang.String to double (found in field 'amount')
at com.google.firebase.firestore.util.CustomClassMapper.deserializeError(com.google.firebase:firebase-firestore@@17.1.4:524)
at com.google.firebase.firestore.util.CustomClassMapper.convertDouble(com.google.firebase:firebase-firestore@@17.1.4:427)
at com.google.firebase.firestore.util.CustomClassMapper.deserializeToPrimitive(com.google.firebase:firebase-firestore@@17.1.4:304)
at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-firestore@@17.1.4:215)
at com.google.firebase.firestore.util.CustomClassMapper.deserializeToType(com.google.firebase:firebase-firestore@@17.1.4:180)
at com.google.firebase.firestore.util.CustomClassMapper.access$200(com.google.firebase:firebase-firestore@@17.1.4:53)
at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-firestore@@17.1.4:700)
at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-firestore@@17.1.4:674)
at com.google.firebase.firestore.util.CustomClassMapper.convertBean(com.google.firebase:firebase-firestore@@17.1.4:503)
at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-firestore@@17.1.4:242)
at com.google.firebase.firestore.util.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-firestore@@17.1.4:97)
at com.google.firebase.firestore.DocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.4:203)
at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.4:121)
at com.google.firebase.firestore.DocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.4:183)
at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.4:101)
at com.firebase.ui.firestore.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:23)
at com.firebase.ui.firestore.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:12)
at com.firebase.ui.common.BaseCachingSnapshotParser.parseSnapshot(BaseCachingSnapshotParser.java:35)
at com.firebase.ui.common.BaseObservableSnapshotArray.get(BaseObservableSnapshotArray.java:52)
at com.firebase.ui.firestore.FirestoreRecyclerAdapter.getItem(FirestoreRecyclerAdapter.java:83)
at com.firebase.ui.firestore.FirestoreRecyclerAdapter.onBindViewHolder(FirestoreRecyclerAdapter.java:125)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6673)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6714)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5647)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5913)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5752)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5748)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2232)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1559)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1519)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:614)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3812)
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3225)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:739)
我知道为什么会引发此错误,并且我也知道如果我在Firestore数据库中更正我的金额字段或通过使用Cloud Function检查数据验证等,就可以更正此问题。
但是我不希望有App崩溃的经历。有没有什么方法可以捕获并添加任何默认值或将Null用于损坏的值。显示单个Null或NA字段或整个空白屏幕总是比Crash更好。
编辑: 为了设置默认值并避免运行时异常,我在Model类中尝试了此操作。我仍然不知道是否有办法捕获此异常。
public double amount;
public double getAmount() {
return amount;
}
// If you change it Object, ClassMapper will not throw any exception and
// You can parse any data type by yourself and also set a default value.
public void setAmount(Object amount) {
try {
// You can also add instanceOf check
this.amount = Double.parseDouble(amount.toString());
} catch (Exception e) {
// Set your default value
this.amount = 0.00;
}
}
答案 0 :(得分:3)
根据您here的要求,我正在回答这个问题。因此,由于我看到您正在使用Firebase-UI库,因此无需使用try-catch块。正如@FrankvanPuffelen在他的评论中提到的那样,您可以做的最简单的事情是像这样在适配器类中覆盖onError
方法:
FirestoreRecyclerAdapter adapter = new FirestoreRecyclerAdapter<Chat, ChatHolder>(options) {
@Override
public void onDataChanged() {
//Called each time there is a new query snapshot.
}
@Override
public void onError(FirebaseFirestoreException e) {
//Handle the error
Log.d(TAG, e.getMessage());
}
};