After I upgraded the Firestore android sdk from v20.1.0 to v21.6.0, my Firestore queries are not working as expected.
If I make a simple get() query or a snapshotListener query (realtime) on a single document, the query works once (or twice) then stops working or getting updates (if realtime query), the onEvent() method wouldn't be triggered.
After deep investigation and multiple tests, we (my work team) found that what causes this is that our documents, each, contain a large Map field with at least 5 levels of multi key-value pairs.
Our map field is called "items", when we tried to remove it from the document, the realtime query works perfectly as expected.
P.S: we tried to check the size of the documents, the average was between 6k bytes and 5k bytes, and Firestore allows 1Mb (1M bytes) as a maximum document size.
To reproduce the bug, follow below steps :
Add this line into your project gradle file :
dependencies {
classpath 'com.google.gms:google-services:4.3.3'
}
Add those two lines into the module:app gradle file :
dependencies {
implementation 'com.google.firebase:firebase-firestore:21.6.0'
implementation 'com.google.code.gson:gson:2.8.6'
}
Add this code to create and write a copy of my document into
firestore :
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" +
"}";
Start a realtime query on this document :
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());
}
}
});
We created two Android projects (Java code), put them into public Github repos so that anyone could reproduce the issue we are facing.
Everything is detailed into the Readme repos.
First Project repository
Second Project repository with minimal code
Before i create this question, i created an issue within the official firebase-android-sdk repository.
After five days, someone from the Firebase team answered me, they did found a bug in the Firestore sdk, fixed it, but still didn't released it, so he recommended to downgrade to older version than 21.5.0 to avoid the bug as a temporary workaround.
Github issue link here
I'm building an Android app that contain SQLite DB and I was having a problem with translating SQLite saved data then I find a solution which is a method to get resource id of strings, and it worked just fine, the app was working fine then suddenly this error showed I don't know why, please help
The method, I used to get resource for string:
public static int getResId(String resName, Class<?> c) {
try {
Field idField = c.getDeclaredField(resName);
return idField.getInt(idField);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
The code in the adapter
textViewname.setText(context.getString(R.string.product_Name)+" " + repo.getName());
textViewquantity.setText(context.getString(R.string.last_added_qty)+" " + repo.getQuantity() + " " + context.getResources().getString(mdatabase.getResId(repo.getItemsType(),R.string.class)));
textViewdate.setText(context.getString(R.string.entry_date)+" " + repo.getDate()+ " /"+context.getResources().getString(mdatabase.getResId(repo.getInOrOut(),R.string.class)));
textViewTotal.setText(context.getString(R.string.total_qty)+" " + repo.getTotal() + " " + context.getResources().getString(mdatabase.getResId(repo.getItemsType(),R.string.class)));
textviewlastUpdated.setText(context.getString(R.string.last_updated_date)+" " + repo.getUpdateDate() +" /"+context.getResources().getString(mdatabase.getResId(repo.getInOrOut(),R.string.class)));
textViewid.setText(context.getString(R.string.id)+" " + repo.getId());
textViewOutputqty.setText(context.getString(R.string.last_out_qty)+" " + repo.getOutputqty() + " " + context.getResources().getString(mdatabase.getResId(repo.getItemsType(),R.string.class)));
textViewpriceofsingleitem.setText(context.getString(R.string.retail_price)+" " + repo.getPrice() + " " + context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewpriceofMultipleitem.setText(context.getString(R.string.wholesale_price)+" " + repo.getPriceofmultipleInput() + " " + context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewProfitSIngle.setText(context.getString(R.string.retail_profit)+" " + repo.getProfitSingle() + " " + context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewProfitMultiple.setText(context.getString(R.string.wholesale_profit)+" " + repo.getProfitMultiple() + " " + context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewPurchasingPrice.setText(context.getString(R.string.purchasing_price)+" " + repo.getPurchasingPricePeranItem() + " " + context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewTotalPurchasingPrice.setText(context.getString(R.string.total_purchase_price)+" " + repo.getTotalPurchasingPrice() + " " + context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewTotalProfitSingle.setText(context.getString(R.string.total_retail_profit)+" " + repo.getTotalProfitperSingle() + " " + context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewTotalProfitMultiple.setText(context.getString(R.string.total_wholesale_profit)+" "+ repo.getTotalProfitPerMultiple() + " " + context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewitemsIBox.setText(context.getString(R.string.num_unitsInBox)+" "+ repo.getItemsInBox());
textViewSinglePriceOfiteminBox.setText(context.getString(R.string.retail_price_perUnit)+ " " + repo.getSinglePriceofItemInBox()+" " +context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewMultipriceOfItemInBox.setText(context.getString(R.string.wholesale_price_perUnit)+" "+repo.getMultiplePriceofitemInBox()+" "+context.getResources().getString(mdatabase.getResId(repo.getCurrency(),R.string.class)));
textViewtotalItemsInBoexs.setText(context.getString(R.string.total_units)+" "+ repo.getTotalitemsInboxes() +" "+ context.getResources().getString(R.string.Pieces));
This error happens because you are trying to get resource that does not exist. It is because you store memory address which allocate to your string resource and possible it will change next time. I do not know what is your scenario but why you store it already in your strings it will never lost. I can help you to build another logic only when you tell what are you trying to achieve.
I am building a web portal through android and a query i am running through JDBC drivers is returning 0 where data should not be zero.
This is the query:
ResultSet set = statement.executeQuery("select it.itcod, it.itnam, it.packn, it.tradp, " +
"sum(nvl(itd.slbox,0) - nvl(itd.srbox,0) - nvl(itd.brbox,0) - nvl(itd.gsbox,0)) as sbox, " +
"sum(nvl(itd.slbbx,0) - nvl(itd.srbbx,0) - nvl(itd.brbbx,0) - nvl(itd.gsbbx,0)) as sbbx, " +
"SUM(NVL(itd.PRBOX,0) - NVL(itd.RPBOX,0) - NVL(itd.TRBOX,0)) as pbox, " +
"SUM(NVL(itd.PRBBX,0) - NVL(itd.RPBBX,0) - NVL(itd.TRBBX,0)) as pbbx " +
"from items it " +
"LEFT join item_daily itd " +
"on (it.cocod = itd.cocod " +
"and it.itcod = itd.itcod " +
"and ITD.ddate between " + fdate + " and " + tdate + ")" +
"WHERE IT.COCOD = " + COCOD +
"AND IT.DCODE = " + DCODE +
"AND NVL(IT.FREZE,'N')!='Y' " +
"group by it.cocod, it.itcod, it.itnam, it.packn, " +
" it.tradp, it.pkqty, it.dcode, it.freze, " +
" it.ishow, it.sltax, it.dcont, it.mcode, " +
" it.nwcod " +
"order by itnam ");
I have tried using resultsetmetadata but that does not work either.
you should be careful to this line
+ fdate + " and " + tdate
because you should use like this:
" .. to_date('"+fdate+"','***your_date_format') and to_date('"+fdate+"','***your_date_format')"