【问题标题】:Can anyone tell me how can I store an array of custom objects in Firebase Firestore (Android)谁能告诉我如何在 Firebase Firestore (Android) 中存储一组自定义对象
【发布时间】:2021-04-15 12:39:18
【问题描述】:

谁能告诉我如何将一组自定义对象从一个应用程序存储到 Firebase Firestore (Android) 中,然后将这些对象检索回另一个应用程序(两个应用程序都连接到同一个 Firebase 项目强>)。 我尝试使用 Maps,并且能够存储订单列表,但无法检索 ArrayList。 这是我的做法:

Map<String, ArrayList<OrderItemModel>> map = new HashMap<>();
map.put(currentOrderNumber, orderList);
firebaseFirestore.collection("orders").document(college).set(map, SetOptions.merge())
        .addOnSuccessListener(new OnSuccessListener<Void>() {
    @Override
    public void onSuccess(Void aVoid) {
        Toast.makeText(getContext(), "Order placed.", Toast.LENGTH_SHORT).show();
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        Toast.makeText(getContext(), "Couldn't place order. Please try again.", Toast.LENGTH_SHORT).show();
        progressBar.setVisibility(View.GONE);
    }
});

当我尝试使用 documentSnapshot.getData() 检索它时,它返回 Map。我尝试将 Object 转换为 ArrayList 并在 RecyclerView 适配器中使用它,但它显示错误。 这是我的 OrderItemModel 类:

public class OrderItemModel {

    private String itemName;
    private String itemPrice;
    private String itemCount;

    public OrderItemModel() {
    }

    public OrderItemModel(String itemName, String itemPrice, String itemCount) {
        this.itemName = itemName;
        this.itemPrice = itemPrice;
        this.itemCount = itemCount;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public String getItemPrice() {
        return itemPrice;
    }

    public void setItemPrice(String itemPrice) {
        this.itemPrice = itemPrice;
    }

    public String getItemCount() {
        return itemCount;
    }

    public void setItemCount(String itemCount) {
        this.itemCount = itemCount;
    }
}

我的 Firebase Firestore:

我已经尝试解决这个问题一个星期,但仍然没有得到任何结果。我已经尝试了很多东西,但仍然找不到解决方案。如果有什么不清楚的请询问。请帮忙。 谢谢。

编辑:

我正在通过以下方式检索数据:

firebaseFirestore.collection("orders").document(college).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
        if (task.isSuccessful()) {
            DocumentSnapshot documentSnapshot = task.getResult();
            assert documentSnapshot != null;
            if (documentSnapshot.exists()) {
                Map<String, Object> listMap = documentSnapshot.getData();
                for (Map.Entry<String, Object> entry : listMap.entrySet()) {
                    Log.d(TAG, "onComplete: Key: " + entry.getKey() + ", Value: " + entry.getValue().toString());
                    if (entry.getKey().equals(currentOrderNumber)) {
                        orderList.addAll((Collection<? extends OrderItemModel>) entry.getValue());
                    }
                }
                Log.d(TAG, "onComplete: ArrayList: " + orderList.get(0).getItemName());         // This line shows error.
                progressBar.setVisibility(View.GONE);
            } else {
                Toast.makeText(ShowOrder.this, "Order document not found!", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(ShowOrder.this, "An error occurred while fetching the data.", Toast.LENGTH_SHORT).show();
        }
    }
});

据我了解,我成功检索了 Map 形式的数据,但无法从中提取 ArrayList。

Log.d(TAG, "onComplete: ArrayList: " + orderList.get(0).getItemName());

上面一行显示以下错误:

2021-01-10 23:48:40.192 8747-8747/com.campuscanteen.main E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.campuscanteen.main, PID: 8747
    java.lang.ClassCastException: java.util.HashMap cannot be cast to com.campuscanteen.main.Models.OrderItemModel
        at com.campuscanteen.main.ShowOrder$2.onComplete(ShowOrder.java:89)
        at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:230)
        at android.app.ActivityThread.main(ActivityThread.java:7815)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:526)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)

编辑 2:

我按照你的建议做了一堂课:

public class OrderList {
    public List<OrderItemModel> modelList;

    public OrderList() {
    }

    @Override
    public String toString() {
        return "OrderList{" +
                "modelList=" + modelList +
                '}';
    }
}

并尝试了这些行来检索数据:

List<OrderItemModel> myLists = documentSnapshot.toObject(OrderList.class).modelList;
                        Log.d(TAG, "onComplete: ArrayList: " + myLists.toString());  // myLists here has null value.

这样列表就有了空值。请原谅我缺乏知识,请帮助。

【问题讨论】:

  • 您在尝试检索数据时能否提供您的代码?它显示什么错误? - 也提供一个例外
  • 如异常所说,您正试图将 HashMap 转换为 OrderItemModel。所以我猜 entry.getValue() 返回类型 HashMap 并且您想在代码行 89 中将其转换为 OrderItemModel。
  • @SlothCoding 是的。我也试过 documentSnapshot.getData().get(currentOrderNumber) 结果是一样的。我不知道该怎么办。你能告诉我一个让arrayList回来的方法吗?我想将arrayList 用于recyclerView。

标签: android firebase google-cloud-firestore development-environment


【解决方案1】:

您收到以下错误:

java.lang.ClassCastException:java.util.HashMap 无法转换为 com.campuscanteen.main.Models.OrderItemModel

因为您试图将 HashMap 类型的对象强制转换为 OrderItemModel 类型的对象,这在 Java 中实际上是不可能的。

看到您的屏幕截图,您的文档包含一个名为“201”的数组类型的属性。该数组包含术语“OrderItemModel”对象。我不确定你为什么要这样称呼这个数组,因为“orderItems”可能更有意义。但是,要将该数组映射到 List&lt;OrderItemModel&gt;,您只需创建一个具有单个属性的类:

class OrdersDocument {
    public List<OrderItemModel> orderItems;
}

现在,您可以创建对文档的引用、附加侦听器并将数组转换为自定义对象列表:

List<OrderItemModel> orderItems = document.toObject(OrdersDocument.class).orderItems;

正如我在以下链接的文章中所解释的:

How to map an array of objects from Cloud Firestore to a List of objects?

【讨论】:

  • 我正在存储客户下的订单。 '201' 是订单号,数组是该订单中的项目。我按照你说的尝试了,但是我得到的数组列表有空值。我不明白这将如何工作(对不起,我是 Android 开发的新手)。我的问题是 - 既然我们已经在 Firestore 中存储了一个 map>,那么我们如何使用一个以 arraylist 作为其成员的类来检索它(它不应该也是一个地图)。在问这个问题之前,我已经查看了你的文章,但没有帮助。我将在“编辑 2:”下添加代码。请帮忙。
  • 请用代码编辑您的问题(不是我的答案)。如果您得到一个空值,这意味着您很可能没有将文档 ID 从“201”更改为“orderItems”。不,它不应该是地图。您可以将整个文档作为 Map 获取,但数组应映射到 List。再试一次,告诉我它是否有效。
  • 对不起,但这次我收到错误消息 - “java.lang.RuntimeException: No properties to serialize found on class com.campuscanteen.main.OrderList”
  • 您收到该错误是因为文档中的数组属性仍被命名为“201”,这是正确的。该属性应命名为“orderItems”。删除该数据并再次添加。如果你需要一个订单的ID,你可以把它添加为类的属性,对吧?
  • 我已经更改了文档名称,但我发现我收到了这个错误,因为我在 OrderList 类中有一个私有成员并且没有 getter。只需添加一个 getter 方法即可解决问题。非常感谢。你帮了大忙。我想在未来再次与您联系以寻求帮助。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
  • 2011-01-17
  • 2018-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多