如何从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:
- Your entity class needs the right setup:
- Make sure the field holding orders is declared as
List<Order>(notArrayList<Order>) - Include a no-argument constructor (Firestore requires this to instantiate the class)
- Ensure your
Orderclass also follows these rules (no-arg constructor, getters/setters for all fields)
- Make sure the field holding orders is declared as
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 }
- Correct way to read the data:
Once your class is set up, you can read the document and convert theListto anArrayListeasily:
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.
Approach 2: Using a Subcollection for Orders (Firestore's Recommended Pattern)
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

