android - 如何将 DocumentReference 传递给 DetailActivity?
问题描述
我正在使用 Firebase 来存储我的数据,并使用 Master/Detail Activity 来显示文档列表,当用户单击其中任何一个时,Detail Activity 应该显示该文档的数据。
问题是我无法将DocumentReference
(Firebase 提供的类)发送到 DetailActivity,intent.putExtra()
因为DocumentReference
它不是可序列化的。
这是我的相关代码:
ListActivity.java
列表项的 OnClickListener,onBindViewHolder
在我的 RecyclerView里面
final View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
Expense item = (Expense) view.getTag();
if (item != null) {
Context context = view.getContext();
Intent intent = new Intent(context, DetailActivity.class);
intent.putExtra(DetailFragment.ARG_ITEM_ID, item);
context.startActivity(intent);
}
else {
Log.e(TAG, "item is null");
}
}
};
DetailFragment.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
Log.d(TAG, getArguments().getSerializable(ARG_ITEM_ID).toString());
Expense item = (Expense) getArguments().getSerializable(ARG_ITEM_ID);
Log.d(TAG, "Received="+item.toString());
}
}
费用.java
public class Expense implements Serializable {
public DocumentReference id;
private String TAG = "Expense";
private Timestamp timestamp;
private float amount;
private String description;
// Do not remove this, it is required by FirebaseFirestore
public Expense() { }
public Expense(float amount, String description, Date timestamp) {
this.timestamp = (timestamp == null) ? Timestamp.now() : new Timestamp(timestamp);
this.amount = amount;
this.description = description;
}
public float getAmount() {
return amount;
}
public String getDescription() { return description; }
public Timestamp getTimestamp() {
return timestamp;
}
public DocumentReference getId() { return id; }
public void setId(DocumentReference id) { this.id = id; }
public String toString() {
Map<String, Object> objectMap = new HashMap<>();
objectMap.put("timestamp", this.timestamp);
objectMap.put("amount", this.amount);
objectMap.put("description", this.description);
return objectMap.toString();
}
}
错误日志
com.example.expenditure E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.expenditure, PID: 9373
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.example.expenditure.NewExpense.Expense)
at android.os.Parcel.writeSerializable(Parcel.java:1833)
at android.os.Parcel.writeValue(Parcel.java:1780)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1584)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at android.os.Parcel.writeValue(Parcel.java:1698)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1584)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at android.content.Intent.writeToParcel(Intent.java:10495)
at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:3823)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1705)
at android.app.Activity.startActivityForResult(Activity.java:5192)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
at android.app.Activity.startActivityForResult(Activity.java:5150)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
at android.app.Activity.startActivity(Activity.java:5521)
at android.app.Activity.startActivity(Activity.java:5489)
at com.example.expenditure.ExpenditureListActivity$1.onClick(ExpenditureListActivity.java:114)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.io.NotSerializableException: com.google.firebase.firestore.DocumentReference
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
解决方案
而不是通过DocumentReference
传递names of the Collection and the Document
,并在中重建 DocumentReference DetailActivity
:
这个:
public class Expense implements Serializable {
public DocumentReference id;
private String TAG = "Expense";
private Timestamp timestamp;
private float amount;
private String description;
.......
public void setId(DocumentReference id) { this.id = id; }
......
变成:
public class Expense implements Serializable {
//add these instead of DocumentReference
public String CollectionName;
public String DocumentName;
private String TAG = "Expense";
private Timestamp timestamp;
private float amount;
private String description;
........
.......
public void setCollectionName(String name) { this.CollectionName= name; }
public void setDocumentName(String name) { this.DocumentName= name; } ......
在您按意图发送项目之前:
.............
Context context = view.getContext();
Intent intent = new Intent(context, DetailActivity.class);
//add these
item.setCollectionName("YOUR_COLLECTION_NAME");
item.setDocumentName("YOUR_DOCUMENT_NAME");
intent.putExtra(DetailFragment.ARG_ITEM_ID, item);
context.startActivity(intent);
...............
在DetailFragment.java
:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
Log.d(TAG, getArguments().getSerializable(ARG_ITEM_ID).toString());
Expense item = (Expense) getArguments().getSerializable(ARG_ITEM_ID);
//reconstruct the document reference
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference docRef = db.collection(item.CollectionName).document(item.DocumentName);
Log.d(TAG, "Received="+item.toString());
}
}
推荐阅读
- php - 如何使两个工作之间的延迟?
- excel - 变量未在 vlookup 中分配
- java - 如何收听 Selenium 中的 CSS 变化?
- jmeter - 杰米特 | 最大虚拟用户容量
- python - matplotlib - 如何并排绘制条形图以比较两列之间的值
- html - Angular File Upload 自定义 mat 错误问题
- javascript - 嵌套项目结构的 npm 重命名错误
- mysql - 如何显示与 2 个不同行比较的值
- php - 使用具有嵌套插件依赖项的自定义 wordpress 插件进行单元测试
- bash - Bash 脚本获取密码并在提示 OpenVPN 客户端连接时使用它?