如何将DocumentReference传递给DetailActivity? [重复]

问题描述 投票:0回答:1

我正在使用Firebase存储我的数据,并且使用主/详细活动显示文档列表,并且当用户单击其中的任何一个时,详细活动应该显示该文档的数据。

问题是我无法通过DocumentReferenceintent.putExtra()(由Firebase提供的类)发送给DetailActivity,因为DocumentReference无法序列化。

这是我的相关代码:

ListActivity.java

清单项目的OnClickListener,在我的RecyclerView的onBindViewHolder

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());
    }
}

Expense.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)
android firebase android-recyclerview google-cloud-firestore master-detail
1个回答
1
投票

而不是传递DocumentReference传递names of the Collection and the Document,并在DetailActivity中重建DocumentReference:

此:

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());
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.