如果文档使用大型 Map 字段,则 Firebase Firestore 查询错误
Posted
技术标签:
【中文标题】如果文档使用大型 Map 字段,则 Firebase Firestore 查询错误【英文标题】:Firebase Firestore query bug if the document uses a large Map field 【发布时间】:2020-09-14 22:05:53 【问题描述】:在我将 Firestore android sdk 从 v20.1.0 升级到 v21.6.0 后,我的 Firestore 查询没有按预期工作。 如果我对单个文档进行简单的 get() 查询或 snapshotListener 查询(实时),查询工作一次(或两次)然后停止工作或获取更新(如果是实时查询),onEvent() 方法不会触发。
经过深入调查和多次测试,我们(我的工作团队)发现造成这种情况的原因是我们的每个文档都包含一个大型 Map 字段,其中至少有 5 级多键值对。 我们的地图字段称为“items”,当我们尝试将其从文档中删除时,实时查询可以正常工作。
P.S:我们尝试检查文档的大小,平均在 6k 字节到 5k 字节之间,Firestore 允许 1Mb(1M 字节)作为最大文档大小。
要重现该错误,请按照以下步骤操作:
将此行添加到您的项目 gradle 文件中:
dependencies
classpath 'com.google.gms:google-services:4.3.3'
将这两行添加到 module:app gradle 文件中:
dependencies
implementation 'com.google.firebase:firebase-firestore:21.6.0'
implementation 'com.google.code.gson:gson:2.8.6'
添加此代码以创建我的文档的副本并将其写入 火库:
private void createAndWriteDocument()
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("MMM d, yyyy HH:mm:ss");
gson = gsonBuilder.create();
FirebaseFirestore.getInstance()
.collection(COLLECTION_ORDERS)
.document("ZYaJKmQF9n1RknziD1tj")
.set(gson.fromJson(jsonOrder2, FireStoreOrder.class));
private final String jsonOrder2 = "\n" +
" \"app_name\":\"Firestore-Sample\",\n" +
" \"app_version\":\"1.0.0\",\n" +
" \"canceled_at\":\"Sep 4, 2020 15:12:34\",\n" +
" \"comments_count\":4,\n" +
" \"countryID\":\"fr\",\n" +
" \"created_at\":\"Sep 4, 2020 12:21:55\",\n" +
" \"currency\":\"EUR\",\n" +
" \"delivered_at\":\"Sep 4, 2020 15:11:30\",\n" +
" \"delivery_agent_id\":\"1rvlTtfJKNVPVxZ2mp4T2CcI1Fj2\",\n" +
" \"delivery_assignment_status\":\"accepted\",\n" +
" \"delivery_fee\":5.0,\n" +
" \"distance\":3.2547,\n" +
" \"hearts_count\":0,\n" +
" \"in_progress_at\":\"Sep 4, 2020 15:06:51\",\n" +
" \"is_friends\":false,\n" +
" \"is_private\":false,\n" +
" \"is_public\":true,\n" +
" \"is_visible\":true,\n" +
" \"items\":\n" +
" \"-MGNqMoKy8YovI11-QUK\":\n" +
" \"category_id\":\"-LlbKEnwkC4KZtJyN691\",\n" +
" \"discount_price\":0.0,\n" +
" \"extras\":\n" +
" \"-M1-qhcXr8tp5KpnLp9p\":\n" +
" \"max\":10,\n" +
" \"name\":\"Chèvre\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":5,\n" +
" \"row\":6\n" +
" ,\n" +
" \"-M1-rHnm7Xzjo7rE73Pk\":\n" +
" \"max\":10,\n" +
" \"name\":\"Vache kiri\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":7,\n" +
" \"row\":4\n" +
" ,\n" +
" \"-M1-me-3qKOqWzul67Sr\":\n" +
" \"is_sub_extra\":true,\n" +
" \"max\":3,\n" +
" \"name\":\"Crispy Tenders\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":0\n" +
" ,\n" +
" \"-M1-mKvK76SYLJBf3zh-\":\n" +
" \"is_sub_extra\":true,\n" +
" \"max\":3,\n" +
" \"name\":\"Escalope de Poulet\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" ,\n" +
" \"-M1-rNaEFCyHlf9WIOaH\":\n" +
" \"max\":10,\n" +
" \"name\":\"Raclette\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":4,\n" +
" \"row\":5\n" +
" \n" +
" ,\n" +
" \"extras_title\":\"Suppléments\",\n" +
" \"ingredients\":\n" +
" \"-MEYbO7SlOBFWUVzcvg6\":\n" +
" \"description\":\"Ingredients description\",\n" +
" \"name\":\"Cheddar\",\n" +
" \"row\":0\n" +
" ,\n" +
" \"-MEYbLvKvqPu3YZPPAjo\":\n" +
" \"description\":\"Ingredients description\",\n" +
" \"name\":\"Laitus\",\n" +
" \"row\":0\n" +
" \n" +
" ,\n" +
" \"ingredients_title\":\"Ingrédients : Décocher pour enlever\",\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582717663739.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582717663739.jpg?alt\\u003dmedia\\u0026token\\u003d1bbfd8a0-be5a-44c2-8dd9-d5a7dacf2243\"\n" +
" ,\n" +
" \"max_extras\":30,\n" +
" \"name\":\"Tacos\",\n" +
" \"options\":\n" +
" \"-LlfWYJR_zKtO1l0DjnF\":\n" +
" \"elements\":\n" +
" \"-LlfWj5L6weXYZUPUoGW\":\n" +
" \"extras_title\":\"3 Viandes\",\n" +
" \"max\":1,\n" +
" \"max_extras\":3,\n" +
" \"min_extras\":3,\n" +
" \"name\":\"L : Choisir 3 Viandes\",\n" +
" \"price\":9.5,\n" +
" \"row\":0\n" +
" \n" +
" ,\n" +
" \"name\":\"Taille\",\n" +
" \"row\":-1\n" +
" ,\n" +
" \"-LlfX5HY1rzcQpz1p6mG\":\n" +
" \"elements\":\n" +
" \"-LlfXbVB-QA-utApD3HO\":\n" +
" \"max\":3,\n" +
" \"name\":\"Barbecue\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" ,\n" +
" \"-LlfXxF-7RRTZhFwXhyX\":\n" +
" \"max\":3,\n" +
" \"name\":\"Marocaine\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" \n" +
" ,\n" +
" \"max_quantity\":4,\n" +
" \"min_quantity\":1,\n" +
" \"name\":\"Sauces\",\n" +
" \"row\":3\n" +
" ,\n" +
" \"-LlfWPIAjjgTiqtqEzep\":\n" +
" \"elements\":\n" +
" \"-LlfWPI9_w1gH1A3HTsB\":\n" +
" \"name\":\"Tacos\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" \n" +
" ,\n" +
" \"name\":\"Type\",\n" +
" \"row\":2\n" +
" \n" +
" ,\n" +
" \"price\":0.0,\n" +
" \"product_id\":\"-LlfTFlgrNBdLZRn5xgn\",\n" +
" \"quantity\":2,\n" +
" \"sub_category_id\":\"-LlbKEnvPMIV3DnSiYlJ\"\n" +
" ,\n" +
" \"-MGNqOGcRfYb-myLgc1d\":\n" +
" \"category_id\":\"-LlkUx5iBSXhKdMYGxTA\",\n" +
" \"discount_price\":3.5,\n" +
" \"extras\":\n" +
" \"-M2JOJaB_Gsc28GT8wEg\":\n" +
" \"max\":2,\n" +
" \"name\":\"Harissa\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":2\n" +
" \n" +
" ,\n" +
" \"extras_title\":\"Sauces\",\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582809519364.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582809519364.jpg?alt\\u003dmedia\\u0026token\\u003dabc457cb-2462-44be-886a-af83db3cb501\"\n" +
" ,\n" +
" \"max_extras\":2,\n" +
" \"name\":\"Oignons frites\",\n" +
" \"options\":\n" +
" \"-M15mpsXwAzsDRlLDHJI\":\n" +
" \"elements\":\n" +
" \"-M15mpsXwAzsDRlLDHJG\":\n" +
" \"name\":\"Cheddar\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" \n" +
" ,\n" +
" \"name\":\"Au choix :\",\n" +
" \"row\":-1\n" +
" \n" +
" ,\n" +
" \"price\":3.5,\n" +
" \"product_id\":\"-M15mV_4Ui2B90GlzsaR\",\n" +
" \"quantity\":1,\n" +
" \"sub_category_id\":\"-LlkUx5h8rXECP8L_hjQ\"\n" +
" ,\n" +
" \"-MGNqOxoHFGoigUXao96\":\n" +
" \"category_id\":\"-LlkUx5iBSXhKdMYGxTA\",\n" +
" \"discount_price\":3.5,\n" +
" \"extras\":\n" +
" \"-M2JOmBf1oN1BmUUHeiY\":\n" +
" \"name\":\"Biggy burger\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":0\n" +
" \n" +
" ,\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582809369789.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582809369789.jpg?alt\\u003dmedia\\u0026token\\u003d705593e0-e403-4931-b040-5b2261cb96e5\"\n" +
" ,\n" +
" \"name\":\"Bacon frites\",\n" +
" \"options\":\n" +
" \"-M15lyQyHs1GujtZxMtS\":\n" +
" \"elements\":\n" +
" \"-M15lyQxrRFaLAWGaa3i\":\n" +
" \"name\":\"Sauce fromagère\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" \n" +
" ,\n" +
" \"name\":\"Au choix :\",\n" +
" \"row\":-1\n" +
" \n" +
" ,\n" +
" \"price\":3.5,\n" +
" \"product_id\":\"-M15lqmhF16ZOLqebPzs\",\n" +
" \"quantity\":1,\n" +
" \"sub_category_id\":\"-LlkUx5h8rXECP8L_hjQ\"\n" +
" \n" +
" ,\n" +
" \"itemsCount\":0,\n" +
" \"level_one_zone_id\":\"Île-de-France\",\n" +
" \"level_two_zone_id\":\"Paris\",\n" +
" \"order_id\":\"ZYaJKmQF9n1RknziD1tj\",\n" +
" \"order_number\":31,\n" +
" \"order_type\":\"delivery\",\n" +
" \"paid\":false,\n" +
" \"paid_with_loyalty\":0.0,\n" +
" \"picked_at\":\"Sep 4, 2020 15:12:46\",\n" +
" \"platform\":\"android\",\n" +
" \"processedAt\":\n" +
" \"nanoseconds\":994000000,\n" +
" \"seconds\":1599228406\n" +
" ,\n" +
" \"restaurant_photo\":\"https://firebasestorage.googleapis.com/v0/b/menutium-319d0.appspot.com/o/LHx3fTdtoaRlrAHSjznJSaPz9rP2%2F-MEYUb7iepk3pLwUyWX3%2Fprofile%2F1597250393877.jpg?alt\\u003dmedia\\u0026token\\u003dcbccd3fe-91fd-4397-ab34-79f5f241def2\",\n" +
" \"status\":\"picked\",\n" +
" \"store_id\":\"-MEYUb7iepk3pLwUyWX3\",\n" +
" \"store_name\":\"La Fourchette\",\n" +
" \"total_price\":50.2,\n" +
" \"updated_at\":\"Sep 7, 2020 18:54:02\",\n" +
" \"user_address\":\"166 Quai de Stalingrad, 92130 Issy-les-Moulineaux, France\\nIssy-les-Moulineaux\",\n" +
" \"user_coordinates\":\"48.8256954,2.2579879\",\n" +
" \"user_name\":\"Mo Salah\",\n" +
" \"user_phone\":\"+21650001002\",\n" +
" \"user_photo\":\"https://firebasestorage.googleapis.com/v0/b/menutium-319d0.appspot.com/o/2Bz8euUmPgMqc4Z7QZWJjLfsgV72%2Fphoto_profile?alt\\u003dmedia\\u0026token\\u003df5dcee5b-fdda-45bd-9ec3-982cfe7832bd\",\n" +
" \"user_uid\":\"2Bz8euUmPgMqc4Z7QZWJjLfsgV72\",\n" +
" \"validated_at\":\"Sep 4, 2020 15:12:42\",\n" +
" \"validatedBy\":\n" +
" \"name\":\"Urban-Admin\",\n" +
" \"id\":\"admin\"\n" +
" \n" +
"";
开始对此文档的实时查询:
FirebaseFirestore.getInstance()
.collection("orders")
.document("ZYaJKmQF9n1RknziD1tj")
.addSnapshotListener(new EventListener<DocumentSnapshot>()
@Override
public void onEvent(@Nullable DocumentSnapshot value,
@Nullable FirebaseFirestoreException error)
Log.d("testing", "onEvent triggered");
if (error != null)
Log.i("testing", "test error : "+ error.getMessage());
);
我们创建了两个 Android 项目(Java 代码),将它们放入公共 Github 存储库,以便任何人都可以重现我们面临的问题。
自述文件中详细介绍了所有内容。
First Project repository
Second Project repository with minimal code
【问题讨论】:
在 Stack Overflow 上,必须将相关代码复制到问题中 - 请编辑问题以执行此操作。不要链接到外部资源,因为这些资源不能保证与此问题具有相同的生命周期,并且将来对其他人没有帮助。 Doug 的评论是有效的,另一方面,如果你确定这是一个错误,请在firebase.google.com/support/troubleshooter/report/bugs 提出这个问题 感谢大家的评论。我确实发送了关于 firebase 疑难解答的错误报告。我正在考虑我应该在我的问题中设置什么代码,因为 *** 只接受 30k 个字符:'( 您应该展示重现问题的完整、最少的代码。 ***.com/help/minimal-reproducible-example @DougStevenson,先生,请考虑认真对待这个问题,我们已经使用 Firebase Firestore 一年多了,我们从来没有遇到过这样的错误,它总是很快,而且性能很好。我们必须降级到 v20.1.0 才能让我们的应用程序正常工作。如果重现问题的最少代码超过 *** 中允许的最大字符数怎么办?我们只是关闭问题?显然,据我所知,在 Github 中创建一个免费的公共存储库,使用最少的代码来重现问题是最佳实践。 【参考方案1】:在我创建这个问题之前,我在官方 firebase-android-sdk 存储库中创建了一个问题。 五天后,Firebase 团队的人回复了我,他们确实在 Firestore sdk 中发现了一个错误,修复了它,但仍然没有发布,所以他建议降级到 21.5.0 之前的版本以避免该错误临时解决方法。 Github问题链接here
【讨论】:
以上是关于如果文档使用大型 Map 字段,则 Firebase Firestore 查询错误的主要内容,如果未能解决你的问题,请参考以下文章