openfoodfacts / smooth-app

🤳🥫 The new Open Food Facts mobile application for Android and iOS, crafted with Flutter and Dart
https://world.openfoodfacts.org/open-food-facts-mobile-app?utm_source=off&utf_medium=web&utm_campaign=github-repo
Apache License 2.0
827 stars 277 forks source link

Ensure that Smoothie can read and migrate the database of Open Food Facts v1 on Android #1234

Closed teolemon closed 2 years ago

teolemon commented 2 years ago

What

monsieurtanuki commented 2 years ago

@teolemon We need help from the Android team here, to provide us with each needed table creation script:

teolemon commented 2 years ago

@VaiTon would like to have your input on that one.

VaiTon commented 2 years ago

The class DaoMaster is generated dinamically by the Gradle GreenDao plugin during build.

I'm not sure though how we'll be able to read from the native app DB since we're using another ID and android doesn't allows to read from a different app unless stated otherwise by the native app.

M123-dev commented 2 years ago

But changing the app id shouldn't be a big problem right

monsieurtanuki commented 2 years ago

@VaiTon Among the hypotheses was the perilous option to let "smoothie" pretend being a next version of the current android app (same package), in which case we would have been able to use the existing database. But that would be very dangerous, wouldn't it?

Anyway, the first question is: "is there a way to get the schema of the current android database, possibly with the meaning of each column?". Like, the generated DaoMaster code?

But changing the app id shouldn't be a big problem right

@M123-dev I don't share your optimism...

teolemon commented 2 years ago

The idea is to swap the app, so the Flutter app would become source wise org.openfoodfacts.scanner, and the Classic Android app would become the current org.openfoodfacts.app

teolemon commented 2 years ago

It does have to be done carefully

VaiTon commented 2 years ago

Anyway, the first question is: "is there a way to get the schema of the current android database, possibly with the meaning of each column?". Like, the generated DaoMaster code?

Every table is made of rows represented by GreenDao @Entityes.

You can find the Entities classes here (except the MapOfStringsToStringConverter.java)

They are the only classes in java because GreenDAO does not support Kotlin so no way to convert them.

monsieurtanuki commented 2 years ago

It does have to be done carefully

@teolemon I like your understatement, so British :)

Thank you @VaiTon for those details. From what I read in the code the problem is that I do know relational databases (like SQLite), but not at all GreenDao annotations.

And the main trouble with all that "swap" idea is that I cannot picture how to test the migration from one android version of the app to the flutter version of the same app.

I definitely think we should rather implement some kind of data sync between android and the server, and between flutter and the server (and of course ios / server). That way we implement a meaningful, testable and reusable code.

VaiTon commented 2 years ago

IMHO the only thing worth moving (if any) are user lists. Offline products are not made to stay indefinetly in local storage and allergens can be set at the app first start.

teolemon commented 2 years ago

history being a userlist. agreed @VaiTon as for storing user data on the server, not a big fan at this point.

VaiTon commented 2 years ago

If that's the case we can think of implementing a custom content provider into the native app and then query it from flutter (idk if that's possible) as stated in this post to get a csv/json/interoperable format that we can parse in flutter.

monsieurtanuki commented 2 years ago

Indeed it would make sense to be able to:

That mechanism

monsieurtanuki commented 2 years ago

Would you guys want me to work on a module that imports a product lists json?

[Edit]: little detail - for the moment we only have "history" and "scan history" lists in smoothie, no user-defined lists.

teolemon commented 2 years ago

That would be awesome. The history would be a very good first point, without any user visible distinction as to whether they were scanned or opened by other means (like I believe is already the case) And very clearly being able to preserve user-defined lists is a must for app swap.

monsieurtanuki commented 2 years ago

@teolemon Ok then. I'll work on a structure similar to this one:

{
   "list": ["12345", "23456", "34567"],
   "data":{
      "12345": {"qty":5}
   }
}

Probably for "history" we won't have a "data" section, unless you keep timestamps (we currently don't in smoothie).

VaiTon commented 2 years ago

@monsieurtanuki what's the use of data? We only keep a list of barcodes and a timestamp for products in history

monsieurtanuki commented 2 years ago

@VaiTon The use of data is optional.

In previous smoothie versions there were data attached to products (for a shopping list a quantity, for a pantry a list of qty * "best before" dates, for history a "last seen" date). And I think shopping lists are still in the pipes for flutter, therefore we need at least to think about product data. As opposed to a mere json-encoded string list which wouldn't allow us to grow, structure-wise.

That said, regarding the migration from android

teolemon commented 2 years ago

any update on this ?

monsieurtanuki commented 2 years ago

@teolemon I'm starting an export/import feature on Smoothie, that can be used "internally" from list to list, perhaps through the clipboard.

teolemon commented 2 years ago

I've updated and clarified the issue, based on the discussion here and on #1735 cc @VaiTon

g123k commented 2 years ago

Here is the plan that we've discussed the other day during the community event:

M123-dev commented 2 years ago

I'd say a dedicated folder would be enough but feel free to create a new package, I mean we already have the folder structure for that

monsieurtanuki commented 2 years ago

@g123k Understood. I hope you guys already have your Android and ios versions on your devices, with populated lists, and that the flutter version switch will not delete somehow the databases. Regardless of the way barcode lists are going to be extracted from the legacy databases, we need an async method that takes the barcode list, downloads all the related products and stores both the list and the products locally. I can do that. I guess a migration folder in the existing smoothie package would do the trick. We may even reuse that code later for barcode list sharing between friends.

g123k commented 2 years ago

Hi,

A quick world after this morning's presentation, where the migration on Android is mostly OK. We can export credentials, history, and user lists from V1.

Regarding the architecture, we have two packages:

On Smoothie, the import feature has been a little tweaked and used (thanks @monsieurtanuki) to now support history and credentials.

The migration is started on the first launch. If for some reason, it failed, it will retry later (a maximum number of retries is implemented). We also consider the credentials import as non-blocking because the user may have changed his password.

A few things are still in progress (e.g.: limiting the number of requests with a large history…), but for Android, we can assume that it's OK. Before releasing any PR, I prefer to finish implementing the iOS part, to be sure I don't have to change the API between Smoothie <-> package.

If you have any questions, feel free to do so!