You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Firestore云数据库读取文档中的ArrayList?餐厅APP开发求助

Hey there! Let's tackle your Firestore data storage issue for your restaurant app—both approaches you tried have their own quirks, so let's break down what's going wrong and how to fix it.

Approach 1: Storing Orders as an Array Field (and Fixing the Read Issue)

First, let's address why your DocumentSnapshot.toObject(MyClassOfList.class) isn't working when the document contains an ArrayList. Firestore's Array type maps best to Java/Kotlin's List interface, not the concrete ArrayList class directly. Plus, there are a few serialization rules you might be missing:

  1. Your entity class needs the right setup:
    • Make sure the field holding orders is declared as List<Order> (not ArrayList<Order>)
    • Include a no-argument constructor (Firestore requires this to instantiate the class)
    • Ensure your Order class also follows these rules (no-arg constructor, getters/setters for all fields)

Here's an example of a properly structured user class:

public class RestaurantUser {
    private String userId;
    private String fullName;
    private List<Order> orders;

    // Required no-arg constructor
    public RestaurantUser() {}

    // Constructor with parameters
    public RestaurantUser(String userId, String fullName, List<Order> orders) {
        this.userId = userId;
        this.fullName = fullName;
        this.orders = orders;
    }

    // Getters and setters for all fields
    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }

    // ... other getters/setters for userId and fullName
}
  1. Correct way to read the data:
    Once your class is set up, you can read the document and convert the List to an ArrayList easily:
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("users").document("user123")
    .get()
    .addOnSuccessListener(docSnapshot -> {
        if (docSnapshot.exists()) {
            RestaurantUser user = docSnapshot.toObject(RestaurantUser.class);
            if (user != null) {
                // Convert List to ArrayList if you need that concrete type
                ArrayList<Order> userOrders = new ArrayList<>(user.getOrders());
                // Use your orders list here!
            }
        }
    })
    .addOnFailureListener(e -> {
        // Handle errors (e.g., network issues, missing document)
        Log.e("FirestoreError", "Failed to read user data", e);
    });

If you still run into issues, double-check that your Order class has all the necessary fields matching what's stored in Firestore, and that each field has a getter and setter.

Your second approach—creating a subcollection where each document represents a single order—is actually the best practice for Firestore, especially for a restaurant app where orders might grow in number or need individual updates. Here's why this works better:

  • No limits on the number of orders (unlike array fields, which are capped at 1MB total size per document)
  • You can easily update, delete, or query individual orders (e.g., "get all orders placed in the last hour")
  • Better scalability as your user base and order volume grows

Example Code for This Approach

Writing an Order to the Subcollection

String userId = "user123";
// Generate a unique ID for the new order
String orderId = db.collection("users").document(userId).collection("orders").document().getId();

Order newOrder = new Order(orderId, "Cheeseburger", 2, 19.99, "pending");
db.collection("users").document(userId).collection("orders").document(orderId)
    .set(newOrder)
    .addOnSuccessListener(aVoid -> {
        Log.d("FirestoreSuccess", "Order saved successfully");
    })
    .addOnFailureListener(e -> {
        Log.e("FirestoreError", "Failed to save order", e);
    });

Reading All Orders for a User

db.collection("users").document(userId).collection("orders")
    .get()
    .addOnSuccessListener(querySnapshot -> {
        ArrayList<Order> userOrders = new ArrayList<>();
        for (DocumentSnapshot orderDoc : querySnapshot) {
            Order order = orderDoc.toObject(Order.class);
            userOrders.add(order);
        }
        // Use your complete orders list here
    })
    .addOnFailureListener(e -> {
        Log.e("FirestoreError", "Failed to fetch orders", e);
    });

Which Approach Should You Choose?

  • Use the array field method only if you're certain each user will have a very small number of orders (like <10) and you never need to modify individual orders.
  • Stick with the subcollection method for most restaurant app use cases—it's more flexible, scalable, and aligns with Firestore's design principles.

内容的提问来源于stack exchange,提问作者George Oprea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:37:46