frozen-burrito / hydrate-app Goto Github PK
View Code? Open in Web Editor NEWRepositorio para la app de apoyo de la botella hydrate, desarrollada con Flutter.
Repositorio para la app de apoyo de la botella hydrate, desarrollada con Flutter.
Descripción del Error
La API REST recibió cambios que implementaron un sistema de paginación de resultados. El widget ArticleSliverList
y las clases ArticleCollection
y ArticleProvider
no son compatibles con este cambio.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
El comportamiento de las clases con la API paginada todavía no está especificado. Probablemente, lo mejor sería implementar un "scroll infinito", que solicite artículos a la API conforme el usuario vaya llegando al final de la lista de artículos. La clase ArticleCollection
debe ser capaz de transformar el resultado JSON de la API a un resultado significativo para la app.
**Entorno **
La app funciona con slivers, que permiten hacer scroll en varias direcciones y en distintos niveles.
Por ejemplo, para hacer scroll horizontal por la navegación principal y luego scroll vertical en cada una de las pestañas.
El problema es en la pestaña de artículos, que a su vez tiene otro TabBarView que hace scroll horizontal y varios slivers de sroll vertical. Para integrarlos hace falta NestedScrollView, que controla el scroll anidado.
Actualmente, el usuario puede desplazarse horizontalmente entre artículos nuevos y guardados, así como verticalmente por cada lista de articulos. Esto invalida el scroll horizontal para navegar a inicio o historial, por ejemplo.
El error es:
The following assertion was thrown building SliverPersistentHeader(delegate: Instance of '_SliverCustomHeaderDelegate', mode: [floating]):
A _RenderSingleChildViewport expected a child of type RenderBox but received a child of type _RenderSliverFloatingPersistentHeaderForWidgets.
RenderObjects expect specific types of children because they coordinate with their children during layout and paint. For example, a RenderSliver cannot be the child of a RenderBox because a RenderSliver does not understand the RenderBox layout protocol.
The _RenderSingleChildViewport that expected a RenderBox child was created by: _SingleChildViewport ← IgnorePointer-[GlobalKey#6624b] ← Semantics ← Listener ← _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#ca79e] ← Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#c7223] ← RepaintBoundary ← CustomPaint ← RepaintBoundary ← ⋯
The _RenderSliverFloatingPersistentHeaderForWidgets that did not match the expected child type was created by: _SliverFloatingPersistentHeader ← SliverPersistentHeader ← _SingleChildViewport ← IgnorePointer-[GlobalKey#6624b] ← Semantics ← Listener ← _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#ca79e] ← Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#c7223] ← RepaintBoundary ← ⋯
The relevant error-causing widget was
SliverPersistentHeader
Necesito ver más sobre NestedScrollView y slivers.
Al pasar un id específico en su método toMap()
, SQLite intenta crear un registro con ese mismo id, que es 0 por defecto. Cuando previamente existe un registro, SQLite marca el error:
SqfliteDatabaseException (DatabaseException(UNIQUE constraint failed: reporte_habitos.id (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY[1555])) sql 'INSERT INTO reporte_habitos (id, horas_sueno, horas_act_fisica, horas_ocupacion, temperatura_max, fecha) VALUES (?, ?, ?, ?, ?, ?)' args [0, 0, 0, 0, 0, 2022-03-01T20:46:45.833798])
Por el error de constraint con primary keys unicos.
Descripción del Error
Al modificar los valores de campos que usan el nuevo esquema para validación y construcción de mensajes de error, hay ciertos valores para ciertos campos que producen tipos de errores que, por el momento, no producen un mensaje de error dedicado.
Algunos ejemplos son:
Unhandled username/email validation message for error: UsernameError.incorrectUsernameFormat
I/flutter (22583): Unhandled activity record distance validation message for error: NumericInputError.isNaN
I/flutter (22583): Unhandled activity record kCal validation message for error: NumericInputError.isNaN
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Las funciones de validación deben producir el error adecuado para cada posible clase de valor de entrada y el constructor de mensajes localizados debe manejar los casos para cada tipo de error producido por los validadores.
Entorno
Contexto Adicional
Posiblemente es buena idea revisar las pruebas unitarias para los validators.
Al intentar usar el método insert(SQLiteModel entity)
de SQLiteDB
con el modelo Article
, surge la siguiente advertencia:
Invalid argument 2022-02-21 21:44:29.785877 with type DateTime.
Only num, String and Uint8List are supported. See [https://github.com/tekartik/sqflite/blob/master/sqflite/doc/supported_types.md]() for details
This will throw an exception in the future. For now it is displayed once per type.
Probablemente hace falta convertir la fecha en DateTime
a un ISO String.
Descripción del Error
Cuando un usuario cambia de perfil, el cambio no es evidente y no hay una transición que lo indique (ya sea en un inicio de sesión, creación de cuenta, cierre de sesión). Además, cambiar el perfil no cambia los datos del perfil anterior por los del nuevo perfil de muchos providers (incluyendo metas, registros de hidratación y actividad física, entre otros)
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Cada perfil debe tener sus metas, registros de actividad, progreso y otros datos dedicados. Un perfil no debería poder visualizar los datos de otro perfil. Al cambiar de perfil, la app debe obtener los datos asociados con el nuevo perfil.
Entorno
Descripción del Error
Parece que las barras en la gráfica de hidratación quedan con valores de 0, aún cuando hay consumo de agua.
Cómo Reproducir
Pasos para reproducir el error:
1.Abrir la aplicación.
2. Navegar a la pestaña de historial.
3. Observar que las gráficas de barras no cambian cuando los registros de hidratación/actividad son cargados.
Comportamiento Esperado
La gráfica primero debería mostrar todas las barras con un valor de 0. Cuando los registros son obtenidos desde la BD con un future, la gráfica debería hacer una transición para mostrar los valores obtenidos.
**Entorno **
Descripción del Error
El servicio de sincronización de actividad física entre la app y Google Fit no guarda las sesiones obtenidas para el perfil de usuario. Esto hace que los registros de actividad no sean visibles fuera de la consola. Tampoco se actualiza la fecha de sincronización con Google Fit en el perfil de usuario activo.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
La app debería guardar las actividades obtenidas desde Google Fit, y debería persistir la fecha de la última sincronización para evitar registros duplicados.
Entorno
La funcionalidad que sugieres surgió de un problema? Por favor descríbelo.
Otras entidades están asociadas al ID del perfil del usuario activo. De esta forma metas, registros de hidratación y demás son propios de un solo perfil, en vez de ser compartidos sin importar el perfil.
Describe la solución que te gustaría
Es posible hacer que cada Article
incluya un campo para el ID del perfil de usuario que lo marcó.
Describe las alternativas que has considerado
También puede dejarse como está, sin problemas por compartir bookmarks.
Contexto adicional
Es importante que, si se decide asociar cada Article
con un perfil de usuario, hará falta definir la funcionalidad y compatibilidad con la API de recursos informativos, además de si deberían ser respaldados.
Descripción del Error
La vista de perfil tiene dos problemas visuales:
ProfileForm
, la cuenta de caracteres del nombre y apellido no es actualizada conforme el usuario escribe.Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
El texto con el nombre completo del perfil debería tener alineación centrada y recortar nombres que usen más de dos líneas. En modo edición, los campos de nombre y apellido deberían actualizar y mostrar la cuenta de caracteres con los cambios a nombre y apellido.
Entorno
Descripción del Error
Cuando no hay recursos informativos disponibles y el usuario navega a la pestaña de exploración en la vista de recursos informativos, la app mantiene el indicador de carga y no muestra un resultado, aún cuando la petición fue realizada con éxito y se confirmó que no hay recursos informativos en el resultado.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
La app debería mostrar un placeholder cuando no hay recursos informativos disponibles o cuando ocurre un error durante el fetch, como lo hace en la pestaña de recursos informativos marcados.
Entorno
La funcionalidad que sugieres surgió de un problema? Por favor descríbelo.
Hay ciertas funciones de la app que no son mostradas de una forma tan clara, como las recompensas por actividad o cuando se registra un nuevo consumo de agua. También hay detalles que pueden mejorar con animaciones simples o colores / efectos diferentes.
Describe la solución que te gustaría
Hay varias mejoras que se pueden hacer, si es que hay tiempo, descritas en el proyecto "Mejoras de UX"
Descripción del Error
El widget InitialForm
usa un FutureBuilder
para obtener el perfil de usuario actual cuando es usado en la página de perfil. El problema sucede cuando InitialForm
es usado para crear el primer perfil local, porque todavía no hay un perfil de usuario creado. Esto hace que se quede intentando obtener un perfil indefinidamente.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Cuando el usuario abre la app por primera vez, la app debería mostrar el formulario de inicio para que el usuario cree su perfil. El usuario puede elegir no completar los datos del perfil inicial, pero siempre debe mostrarse el formulario.
**Entorno **
Descripción del Error
Los registros de hidratación pueden ser sincronizados correctamente desde la extensión para botellas, pero en ciertas condiciones todavía no identificadas, invocar los métodos characteristic.read()
y characteristic.write(bytes)
resulta en una Exception
genérica no manejada.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Invocar los métodos characteristic.read()
y characteristic.write(bytes)
nunca debería producir un error mientras el dispositivo se encuentre conectado. Las invocaciones a estos métodos deberían ser sincronizadas correctamente.
Entorno
Contexto Adicional
La salida por consola de la app:
(...)
V/InputMethodManager(23953): Starting input: tba=com.example.ble_prototype ic=null mNaviBarColor -16711423 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false
D/InputMethodManager(23953): startInputInner - Id : 0
I/SurfaceControl(23953): nativeRelease nativeObject s[507572011936]
I/SurfaceControl(23953): nativeRelease nativeObject e[507572011936]
I/SurfaceControl(23953): nativeRelease nativeObject s[507572013088]
I/SurfaceControl(23953): nativeRelease nativeObject e[507572013088]
D/FlutterBluePlugin(23953): mDevices size: 0
D/FlutterBluePlugin(23953): mDevices size: 0
D/FlutterBluePlugin(23953): mDevices size: 0
(...)
D/FlutterBluePlugin(23953): mDevices size: 0
I/ViewRootImpl@87b963[MainActivity](23953): ViewPostIme pointer 0
I/ViewRootImpl@87b963[MainActivity](23953): ViewPostIme pointer 1
I/BluetoothAdapter(23953): STATE_ON
I/BluetoothAdapter(23953): STATE_ON
I/BluetoothAdapter(23953): STATE_ON
I/BluetoothAdapter(23953): STATE_ON
D/BluetoothLeScanner(23953): Start Scan with callback
D/BluetoothLeScanner(23953): onScannerRegistered() - status=0 scannerId=13 mScannerId=0
D/FlutterBluePlugin(23953): mDevices size: 0
D/FlutterBluePlugin(23953): mDevices size: 0
D/FlutterBluePlugin(23953): mDevices size: 0
I/BluetoothAdapter(23953): STATE_ON
I/BluetoothAdapter(23953): STATE_ON
D/BluetoothLeScanner(23953): Stop Scan with callback
I/ViewRootImpl@87b963[MainActivity](23953): ViewPostIme pointer 0
I/ViewRootImpl@87b963[MainActivity](23953): ViewPostIme pointer 1
I/flutter (23953): Device state changed BluetoothDeviceState.disconnected
D/FlutterBluePlugin(23953): mDevices size: 0
D/FlutterBluePlugin(23953): mDevices size: 0
I/ViewRootImpl@87b963[MainActivity](23953): ViewPostIme pointer 0
I/ViewRootImpl@87b963[MainActivity](23953): ViewPostIme pointer 1
I/flutter (23953): Connecting to device
I/BluetoothAdapter(23953): STATE_ON
D/BluetoothGatt(23953): connect() - device: E0:E2:E6:9B:3B:C2, auto: true
I/BluetoothAdapter(23953): isSecureModeEnabled
D/BluetoothGatt(23953): registerApp()
D/BluetoothGatt(23953): registerApp() - UUID=8e6ad573-ac61-4ef0-91e0-aabb0ad2663d
D/BluetoothGatt(23953): onClientRegistered() - status=0 clientIf=13
D/BluetoothGatt(23953): onClientConnectionState() - status=0 clientIf=13 device=E0:E2:E6:9B:3B:C2
D/FlutterBluePlugin(23953): [onConnectionStateChange] status: 0 newState: 2
I/flutter (23953): Device state changed BluetoothDeviceState.connected
I/flutter (23953): Device connected, discovering services
D/BluetoothGatt(23953): discoverServices() - device: E0:E2:E6:9B:3B:C2
D/BluetoothGatt(23953): onConnectionUpdated() - Device=E0:E2:E6:9B:3B:C2 interval=24 latency=0 timeout=400 status=0
D/BluetoothGatt(23953): onConnectionUpdated() - Device=E0:E2:E6:9B:3B:C2 interval=6 latency=0 timeout=500 status=0
D/BluetoothGatt(23953): onSearchComplete() = Device=E0:E2:E6:9B:3B:C2 Status=0
D/FlutterBluePlugin(23953): [onServicesDiscovered] count: 4 status: 0
D/BluetoothGatt(23953): onConnectionUpdated() - Device=E0:E2:E6:9B:3B:C2 interval=24 latency=0 timeout=400 status=0
D/BluetoothGatt(23953): setCharacteristicNotification() - uuid: 0faf892f-0000-1000-8000-00805f9b34fb enable: true
I/flutter (23953): Handling change on pendingRecordsCount: []
I/flutter (23953): Pending record count bytes is empty, no data.
D/FlutterBluePlugin(23953): [onDescriptorWrite] uuid: 00002902-0000-1000-8000-00805f9b34fb status: 0
D/FlutterBluePlugin(23953): [onCharacteristicChanged] uuid: 0faf892f-0000-1000-8000-00805f9b34fb
D/FlutterBluePlugin(23953): mDevices size: 1
I/flutter (23953): Handling change on pendingRecordsCount: [1]
I/flutter (23953): Number of records pending sync: 1
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 0faf892c-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
D/FlutterBluePlugin(23953): [onCharacteristicRead] uuid: 0faf892c-0000-1000-8000-00805f9b34fb status: 0
I/flutter (23953): Ml char bytes: [68, 0]
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 00002a6e-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
D/FlutterBluePlugin(23953): [onCharacteristicRead] uuid: 00002a6e-0000-1000-8000-00805f9b34fb status: 0
I/flutter (23953): Temperature char bytes: [247, 255]
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 00000fff-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
D/FlutterBluePlugin(23953): [onCharacteristicRead] uuid: 00000fff-0000-1000-8000-00805f9b34fb status: 0
I/flutter (23953): Date char bytes: [13, 0, 0, 0, 0, 0, 0, 0]
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 0faf892f-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
D/FlutterBluePlugin(23953): [onCharacteristicRead] uuid: 0faf892f-0000-1000-8000-00805f9b34fb status: 0
I/flutter (23953): Ignored device service characteristic, uuid: 0faf892f-0000-1000-8000-00805f9b34fb
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 00002a19-0000-1000-8000-00805f9b34fb serviceUuid: 0000180f-0000-1000-8000-00805f9b34fb
I/flutter (23953): Handling change on pendingRecordsCount: [1]
I/flutter (23953): Number of records pending sync: 1
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 0faf892c-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
I/flutter (23953): Error al leer de la caracteristica con UUID = pendingCountCharGUID: PlatformException(read_characteristic_error, unknown reason, may occur if readCharacteristic was called before last read finished., null, null)
I/flutter (23953): Ml char bytes: []
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 00002a6e-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
I/flutter (23953): Error al leer de la caracteristica con UUID = pendingCountCharGUID: PlatformException(read_characteristic_error, unknown reason, may occur if readCharacteristic was called before last read finished., null, null)
I/flutter (23953): Temperature char bytes: []
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 00000fff-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
I/flutter (23953): Error al leer de la caracteristica con UUID = pendingCountCharGUID: PlatformException(read_characteristic_error, unknown reason, may occur if readCharacteristic was called before last read finished., null, null)
I/flutter (23953): Date char bytes: []
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 0faf892f-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
I/flutter (23953): Error leer de la caracteristica con UUID = pendingCountCharGUID: PlatformException(read_characteristic_error, unknown reason, may occur if readCharacteristic was called before last read finished., null, null)
I/flutter (23953): Ignored device service characteristic, uuid: 0faf892f-0000-1000-8000-00805f9b34fb
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 00002a19-0000-1000-8000-00805f9b34fb serviceUuid: 0000180f-0000-1000-8000-00805f9b34fb
I/flutter (23953): Error al leer de la caracteristica con UUID = pendingCountCharGUID: PlatformException(read_characteristic_error, unknown reason, may occur if readCharacteristic was called before last read finished., null, null)
D/FlutterBluePlugin(23953): [onCharacteristicRead] uuid: 00002a19-0000-1000-8000-00805f9b34fb status: 0
I/flutter (23953): Battery char bytes: []
I/flutter (23953): Synchronized data through BLE: {}
I/flutter (23953): Not all required attributes could be obtained, expected 4
I/flutter (23953): Battery char bytes: [32]
I/flutter (23953): Synchronized data through BLE: {cantidad: 68, temperatura: -0.09, fecha: 1969-12-31 18:00:13.000, porcentaje_bateria: 32}
D/FlutterBluePlugin(23953): [onCharacteristicChanged] uuid: 0faf892f-0000-1000-8000-00805f9b34fb
I/flutter (23953): Handling change on pendingRecordsCount: [1]
I/flutter (23953): Number of records pending sync: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): [onCharacteristicChanged] uuid: 0faf892f-0000-1000-8000-00805f9b34fb
I/flutter (23953): Handling change on pendingRecordsCount: [1]
I/flutter (23953): Number of records pending sync: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): [onCharacteristicChanged] uuid: 0faf892f-0000-1000-8000-00805f9b34fb
I/flutter (23953): Handling change on pendingRecordsCount: [1]
I/flutter (23953): Number of records pending sync: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): [onCharacteristicChanged] uuid: 0faf892f-0000-1000-8000-00805f9b34fb
I/flutter (23953): Handling change on pendingRecordsCount: [1]
I/flutter (23953): Number of records pending sync: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): [onCharacteristicChanged] uuid: 0faf892f-0000-1000-8000-00805f9b34fb
I/flutter (23953): Handling change on pendingRecordsCount: [1]
I/flutter (23953): Number of records pending sync: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): mDevices size: 1
D/FlutterBluePlugin(23953): [onCharacteristicWrite] uuid: 0faf892f-0000-1000-8000-00805f9b34fb status: 133
D/BluetoothGatt(23953): onClientConnectionState() - status=22 clientIf=13 device=E0:E2:E6:9B:3B:C2
D/FlutterBluePlugin(23953): [onConnectionStateChange] status: 22 newState: 0
I/flutter (23953): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 0faf892c-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
I/flutter (23953): Error al escribir a la caracteristica con UUID = pendingCountCharGUID: Exception: Failed to write the characteristic
I/flutter (23953): Hydration record synchronized: Test Hydration record = {id:-1, amount:68 ml, temperature:-0.09 °C, remaining battery:32%, date:1969-12-31T18:00:13.000, profileId:-1, }
I/flutter (23953): Device state changed BluetoothDeviceState.disconnected
D/BluetoothGatt(23953): onClientConnectionState() - status=0 clientIf=13 device=E0:E2:E6:9B:3B:C2
D/FlutterBluePlugin(23953): [onConnectionStateChange] status: 0 newState: 2
I/flutter (23953): Device state changed BluetoothDeviceState.connected
I/flutter (23953): Device connected, discovering services
D/BluetoothGatt(23953): discoverServices() - device: E0:E2:E6:9B:3B:C2
D/BluetoothGatt(23953): onConnectionUpdated() - Device=E0:E2:E6:9B:3B:C2 interval=24 latency=0 timeout=400 status=0
D/BluetoothGatt(23953): onConnectionUpdated() - Device=E0:E2:E6:9B:3B:C2 interval=6 latency=0 timeout=500 status=0
Application finished.
La salida por consola de la extensión para botellas:
I (29) boot: ESP-IDF v4.4.1 2nd stage bootloader
I (29) boot: compile time 19:54:45
I (29) boot: chip revision: 3
I (32) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (39) boot.esp32: SPI Speed : 40MHz
I (44) boot.esp32: SPI Mode : DIO
I (48) boot.esp32: SPI Flash Size : 2MB
I (53) boot: Enabling RNG early entropy source...
I (58) boot: Partition Table:
I (62) boot: ## Label Usage Type ST Offset Length
I (69) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (76) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (84) boot: 2 factory factory app 00 00 00010000 00100000
I (91) boot: End of partition table
I (96) boot_comm: chip revision: 3, min. application chip revision: 0
I (103) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=207f8h (133112) map
I (159) esp_image: segment 1: paddr=00030820 vaddr=3ffbdb60 size=04760h ( 18272) load
I (167) esp_image: segment 2: paddr=00034f88 vaddr=40080000 size=0b090h ( 45200) load
I (186) esp_image: segment 3: paddr=00040020 vaddr=400d0020 size=7fb40h (523072) map
I (375) esp_image: segment 4: paddr=000bfb68 vaddr=4008b090 size=0dcb0h ( 56496) load
I (399) esp_image: segment 5: paddr=000cd820 vaddr=50000000 size=00010h ( 16) load
I (411) boot: Loaded app from partition at offset 0x10000
I (411) boot: Disabling RNG early entropy source...
I (423) cpu_start: Pro cpu up.
I (423) cpu_start: Starting app cpu, entry point is 0x400813a4
0x400813a4: call_start_cpu1 at C:/Espressif/frameworks/esp-idf-v4.4.1-2/components/esp_system/port/cpu_start.c:160
I (0) cpu_start: App cpu up.
I (439) cpu_start: Pro cpu start user code
I (439) cpu_start: cpu freq: 160000000
I (439) cpu_start: Application information:
I (444) cpu_start: Project name: extension-inteligente-hydrate
I (451) cpu_start: App version: 6cb320a-dirty
I (456) cpu_start: Compile time: Sep 20 2022 17:43:26
I (462) cpu_start: ELF file SHA256: aff40b73cb2af185...
I (468) cpu_start: ESP-IDF: v4.4.1
I (473) heap_init: Initializing. RAM available for dynamic allocation:
I (480) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (486) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (492) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (499) heap_init: At 3FFC6DA0 len 00019260 (100 KiB): DRAM
I (505) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (511) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (518) heap_init: At 40098D40 len 000072C0 (28 KiB): IRAM
I (525) spi_flash: detected chip: generic
I (529) spi_flash: flash io: dio
W (533) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (547) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (556) MAIN: Size minimo de heap libre (antes de setup()): 226324 bytes
I (616) MAIN: Size minimo de heap libre (despues de setup()): 223524 bytes
I (3616) BTDM_INIT: BT controller compile version [5688ed5]
I (3616) system_api: Base MAC address is not set
I (3616) system_api: read default base MAC address from EFUSE
I (3616) MAIN: NVS inicializado
I (3626) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
I (3736) BLE: Estado de BLE: Initializing
I (3736) BATTERY: eFuse Two Point: no soportado
I (3736) BATTERY: Characterized using eFuse Vref
I (3736) MAIN: Battery sensor status (ESP_OK)
I (3746) MAIN: MPU6050 device ID: 0
I (4066) BLE: Tabla GATT para HYDR_SVC creada, handle = 10
I (4066) BLE: Tabla GATT para BAT_SVC creada, handle = 3
I (4076) BLE: SERVICE_START_EVT, status 0, service_handle = 40
I (4076) BLE: SERVICE_START_EVT, status 0, service_handle = 50
I (4086) BLE: Advertising comenzado
I (4236) BLE: Estado de BLE: Advertising
I (4736) BLE: Estado de BLE: Advertising
I (5236) BLE: Estado de BLE: Advertising
I (5736) BLE: Estado de BLE: Advertising
I (6236) BLE: Estado de BLE: Advertising
I (6736) BLE: Estado de BLE: Advertising
I (7236) BLE: Estado de BLE: Advertising
I (7736) BLE: Estado de BLE: Advertising
I (8236) BLE: Estado de BLE: Advertising
I (8616) BLE: Estado de BLE: Advertising
I (8616) MAIN: Nuevo registro de hidratacion generado: { water: 74, temp: -2, bat: 16, time: 8}
I (8616) MAIN: Nuevo registro de hidratacion enviado para almacenamiento, total 1
I (8736) BLE: Estado de BLE: Advertising
I (8736) STORAGE: Sample key name: wtr_amount_1
I (8736) STORAGE: Sample key name: temperature_1
I (8736) STORAGE: Sample key name: battery_lvl_1
I (8746) STORAGE: Sample key name: timestamp_1
I (8766) MAIN: Registro almacenado en NVS, con indice = 1
I (9056) BLE: Estado de BLE: Advertising
I (9266) BLE: Estado de BLE: Advertising
I (9766) BLE: Estado de BLE: Advertising
I (10266) BLE: Estado de BLE: Advertising
I (10766) BLE: Estado de BLE: Advertising
I (11266) BLE: Estado de BLE: Advertising
I (11586) BLE: ESP_GATTS_CONNECT_EVT, conn_id = 0
I (11586) BLE: 77 ef 12 a7 9f 0d
I (11586) BLE: Estado de BLE: Paired
I (11766) BLE: Estado de BLE: Paired
I (11766) MAIN: Numero de registros almacenados: 1
I (11776) MAIN: Registro obtenido de NVS: (indice 0) { water: 68, temp: -9, bat: 32, time: 13}
I (11836) BLE: Estado de BLE: Paired
I (11836) BLE: Registro convertido a buffers para ser sincronizado (water_amount, temperature, battery_level, timestamp):
I (11846) BLE: 44 00
I (11846) BLE: f7 ff
I (11846) BLE: 20
I (11846) BLE: 0d 00 00 00 00 00 00 00
I (11856) BLE: ESP_GATTS_CONF_EVT, status = 0, attr_handle = 48
I (11976) BLE: Parámetros de conexión actualizados:
status = 0
min_int = 16
max_int = 32
conn_int = 24
latency = 0
timeout = 400
I (12246) BLE: Parámetros de conexión actualizados:
status = 0
min_int = 0
max_int = 0
conn_int = 6
latency = 0
timeout = 500
I (12276) BLE: Estado de BLE: Paired
I (12276) MAIN: Numero de registros almacenados: 0
I (12546) BLE: Parámetros de conexión actualizados:
status = 0
min_int = 0
max_int = 0
conn_int = 24
latency = 0
timeout = 400
I (12646) BLE: GATT_WRITE_EVT, handle = 49, value len = 2, value :
I (12646) BLE: Hydration service WRITE
I (12646) BLE: 'Notify' activado para HYDR_IDX_CHAR_NUM_NEW_RECORDS_NTF_CFG
I (12656) BLE: ESP_GATTS_CONF_EVT, status = 0, attr_handle = 48
I (12776) BLE: Estado de BLE: Paired
I (12776) MAIN: Numero de registros almacenados: 0
I (12796) BLE: Hydration service READ, attribute index = 2
I (12796) BLE: Respuesta enviada para evento de READ
I (12876) BLE: Hydration service READ, attribute index = 4
I (12886) BLE: Respuesta enviada para evento de READ
I (12946) BLE: Hydration service READ, attribute index = 6
I (12946) BLE: Respuesta enviada para evento de READ
I (13006) BLE: Hydration service READ, attribute index = 8
I (13006) BLE: Respuesta enviada para evento de READ
I (13066) BLE: Battery service READ, attribute index = 2
I (13066) BLE: Respuesta enviada para evento de READ
I (13176) BLE: GATT_WRITE_EVT, handle = 48, value len = 1, value :
I (13186) BLE: Hydration service WRITE
I (13186) BLE: Confirmado: registro fue obtenido por dispositivo periferico
I (13186) MAIN: Registro obtenido por el dispositivo periferico, restantes = 0
I (13196) BLE: Estado de BLE: Paired
I (13276) BLE: Estado de BLE: Paired
I (13276) MAIN: Numero de registros almacenados: 0
I (13456) BLE: Estado de BLE: Paired
I (13626) BLE: Estado de BLE: Paired
I (13626) MAIN: Nuevo registro de hidratacion generado: { water: 68, temp: -9, bat: 32, time: 13}
I (13626) MAIN: Nuevo registro de hidratacion enviado para sincronizacion, total 2
I (13706) BLE: Estado de BLE: Paired
I (13706) BLE: Registro convertido a buffers para ser sincronizado (water_amount, temperature, battery_level, timestamp):
I (13706) BLE: 44 00
I (13716) BLE: f7 ff
I (13716) BLE: 20
I (13716) BLE: 0d 00 00 00 00 00 00 00
I (13726) BLE: ESP_GATTS_CONF_EVT, status = 0, attr_handle = 48
I (13746) BATTERY: ADC2 Channel[7] voltage: 2130 mV
I (13746) MAIN: Carga restante de la bateria: 0%
I (13776) BLE: Estado de BLE: Paired
I (13776) MAIN: Numero de registros almacenados: 0
I (14276) BLE: Estado de BLE: Paired
I (14276) MAIN: Numero de registros almacenados: 0
I (14776) BLE: Estado de BLE: Paired
I (14776) MAIN: Numero de registros almacenados: 0
I (15276) BLE: Estado de BLE: Paired
I (15276) MAIN: Numero de registros almacenados: 0
I (15776) BLE: Estado de BLE: Paired
I (15776) MAIN: Numero de registros almacenados: 0
I (16276) BLE: Estado de BLE: Paired
I (16276) MAIN: Numero de registros almacenados: 0
I (16776) BLE: Estado de BLE: Paired
I (16776) MAIN: Numero de registros almacenados: 0
I (17276) BLE: Estado de BLE: Paired
I (17276) MAIN: Numero de registros almacenados: 0
I (17776) BLE: Estado de BLE: Paired
I (17776) MAIN: Numero de registros almacenados: 0
I (18276) BLE: Estado de BLE: Paired
I (18276) MAIN: Numero de registros almacenados: 0
I (18636) BLE: Estado de BLE: Paired
I (18636) MAIN: Nuevo registro de hidratacion generado: { water: 536, temp: 12, bat: 19, time: 18}
I (18636) MAIN: Nuevo registro de hidratacion enviado para sincronizacion, total 3
W (18726) MAIN: Registro sincronizado, pero no fue obtenido por dispositivo periferico, restantes = 1
I (18726) BLE: Estado de BLE: Paired
I (18726) BLE: Registro convertido a buffers para ser sincronizado (water_amount, temperature, battery_level, timestamp):
I (18736) BLE: 44 00
I (18746) BLE: f7 ff
I (18746) BLE: 20
I (18746) BLE: 0d 00 00 00 00 00 00 00
I (18756) BLE: ESP_GATTS_CONF_EVT, status = 0, attr_handle = 48
I (18776) BLE: Estado de BLE: Paired
I (18776) MAIN: Numero de registros almacenados: 0
I (19276) BLE: Estado de BLE: Paired
I (19276) MAIN: Numero de registros almacenados: 0
I (19776) BLE: Estado de BLE: Paired
I (19776) MAIN: Numero de registros almacenados: 0
I (20276) BLE: Estado de BLE: Paired
I (20276) MAIN: Numero de registros almacenados: 0
I (20776) BLE: Estado de BLE: Paired
I (20776) MAIN: Numero de registros almacenados: 0
I (21276) BLE: Estado de BLE: Paired
I (21276) MAIN: Numero de registros almacenados: 0
I (21776) BLE: Estado de BLE: Paired
I (21776) MAIN: Numero de registros almacenados: 0
I (22276) BLE: Estado de BLE: Paired
I (22276) MAIN: Numero de registros almacenados: 0
I (22776) BLE: Estado de BLE: Paired
I (22776) MAIN: Numero de registros almacenados: 0
I (23276) BLE: Estado de BLE: Paired
I (23276) MAIN: Numero de registros almacenados: 0
I (23646) BLE: Estado de BLE: Paired
I (23646) MAIN: Nuevo registro de hidratacion generado: { water: 642, temp: 34, bat: 25, time: 23}
I (23646) MAIN: Nuevo registro de hidratacion enviado para sincronizacion, total 4
I (23746) BATTERY: ADC2 Channel[7] voltage: 2091 mV
I (23746) MAIN: Carga restante de la bateria: 0%
W (23756) MAIN: Registro sincronizado, pero no fue obtenido por dispositivo periferico, restantes = 1
I (23756) BLE: Estado de BLE: Paired
I (23756) BLE: Registro convertido a buffers para ser sincronizado (water_amount, temperature, battery_level, timestamp):
I (23766) BLE: 44 00
I (23776) BLE: f7 ff
I (23776) BLE: 20
I (23776) BLE: 0d 00 00 00 00 00 00 00
I (23786) BLE: Estado de BLE: Paired
I (23786) BLE: ESP_GATTS_CONF_EVT, status = 0, attr_handle = 48
I (23786) MAIN: Numero de registros almacenados: 0
I (24296) BLE: Estado de BLE: Paired
I (24296) MAIN: Numero de registros almacenados: 0
I (24796) BLE: Estado de BLE: Paired
I (24796) MAIN: Numero de registros almacenados: 0
I (25296) BLE: Estado de BLE: Paired
I (25296) MAIN: Numero de registros almacenados: 0
I (25796) BLE: Estado de BLE: Paired
I (25796) MAIN: Numero de registros almacenados: 0
I (26296) BLE: Estado de BLE: Paired
I (26296) MAIN: Numero de registros almacenados: 0
I (26796) BLE: Estado de BLE: Paired
I (26796) MAIN: Numero de registros almacenados: 0
I (27296) BLE: Estado de BLE: Paired
I (27296) MAIN: Numero de registros almacenados: 0
I (27796) BLE: Estado de BLE: Paired
I (27796) MAIN: Numero de registros almacenados: 0
I (28296) BLE: Estado de BLE: Paired
I (28296) MAIN: Numero de registros almacenados: 0
I (28656) BLE: Estado de BLE: Paired
I (28656) MAIN: Nuevo registro de hidratacion generado: { water: 200, temp: -5, bat: 60, time: 28}
I (28656) MAIN: Nuevo registro de hidratacion enviado para sincronizacion, total 5
W (28786) MAIN: Registro sincronizado, pero no fue obtenido por dispositivo periferico, restantes = 1
I (28786) BLE: Estado de BLE: Paired
I (28786) BLE: Registro convertido a buffers para ser sincronizado (water_amount, temperature, battery_level, timestamp):
I (28796) BLE: 44 00
I (28806) BLE: f7 ff
I (28806) BLE: 20
I (28806) BLE: 0d 00 00 00 00 00 00 00
I (28816) BLE: Estado de BLE: Paired
I (28816) BLE: ESP_GATTS_CONF_EVT, status = 0, attr_handle = 48
I (28816) MAIN: Numero de registros almacenados: 0
I (29326) BLE: Estado de BLE: Paired
I (29326) MAIN: Numero de registros almacenados: 0
I (29826) BLE: Estado de BLE: Paired
I (29826) MAIN: Numero de registros almacenados: 0
I (30326) BLE: Estado de BLE: Paired
I (30326) MAIN: Numero de registros almacenados: 0
I (30826) BLE: Estado de BLE: Paired
I (30826) MAIN: Numero de registros almacenados: 0
I (31326) BLE: Estado de BLE: Paired
I (31326) MAIN: Numero de registros almacenados: 0
I (31826) BLE: Estado de BLE: Paired
I (31826) MAIN: Numero de registros almacenados: 0
I (32326) BLE: Estado de BLE: Paired
I (32326) MAIN: Numero de registros almacenados: 0
I (32826) BLE: Estado de BLE: Paired
I (32826) MAIN: Numero de registros almacenados: 0
I (33326) BLE: Estado de BLE: Paired
I (33326) MAIN: Numero de registros almacenados: 0
I (33666) BLE: Estado de BLE: Paired
I (33666) MAIN: Nuevo registro de hidratacion generado: { water: 132, temp: -35, bat: 47, time: 33}
I (33666) MAIN: Nuevo registro de hidratacion enviado para sincronizacion, total 6
I (33746) BATTERY: ADC2 Channel[7] voltage: 2110 mV
I (33746) MAIN: Carga restante de la bateria: 0%
W (33816) MAIN: Registro sincronizado, pero no fue obtenido por dispositivo periferico, restantes = 1
I (33816) BLE: Estado de BLE: Paired
I (33816) BLE: Registro convertido a buffers para ser sincronizado (water_amount, temperature, battery_level, timestamp):
I (33826) BLE: 44 00
I (33836) BLE: f7 ff
I (33836) BLE: 20
I (33836) BLE: 0d 00 00 00 00 00 00 00
I (33846) BLE: Estado de BLE: Paired
I (33846) BLE: ESP_GATTS_CONF_EVT, status = 0, attr_handle = 48
I (33846) MAIN: Numero de registros almacenados: 0
I (34356) BLE: Estado de BLE: Paired
I (34356) MAIN: Numero de registros almacenados: 0
I (34856) BLE: Estado de BLE: Paired
I (34856) MAIN: Numero de registros almacenados: 0
I (35356) BLE: Estado de BLE: Paired
I (35356) MAIN: Numero de registros almacenados: 0
I (35856) BLE: Estado de BLE: Paired
I (35856) MAIN: Numero de registros almacenados: 0
I (36356) BLE: Estado de BLE: Paired
I (36356) MAIN: Numero de registros almacenados: 0
I (36856) BLE: Estado de BLE: Paired
I (36856) MAIN: Numero de registros almacenados: 0
I (37356) BLE: Estado de BLE: Paired
I (37356) MAIN: Numero de registros almacenados: 0
I (37856) BLE: Estado de BLE: Paired
I (37856) MAIN: Numero de registros almacenados: 0
I (38356) BLE: Estado de BLE: Paired
I (38356) MAIN: Numero de registros almacenados: 0
I (38676) BLE: Estado de BLE: Paired
I (38676) MAIN: Nuevo registro de hidratacion generado: { water: 410, temp: 13, bat: 0, time: 38}
W (38726) MAIN: Un nuevo registro 6 no pudo ser enviado para sincronizacion (errQUEUE_FULL)
W (38846) MAIN: Registro sincronizado, pero no fue obtenido por dispositivo periferico, restantes = 1
I (38846) BLE: Estado de BLE: Paired
I (38856) BLE: Estado de BLE: Paired
I (38856) MAIN: Numero de registros almacenados: 0
I (39356) BLE: Estado de BLE: Paired
I (39356) MAIN: Numero de registros almacenados: 0
I (39856) BLE: Estado de BLE: Paired
I (39856) MAIN: Numero de registros almacenados: 0
I (40356) BLE: Estado de BLE: Paired
I (40356) MAIN: Numero de registros almacenados: 0
I (40856) BLE: Estado de BLE: Paired
I (40856) MAIN: Numero de registros almacenados: 0
Al enviar el formulario, solo se verifica el primer campo. Cuando los demás campos tienen valores incorrectos y el primero si está bien, el proceso sigue como si nada.
Tampoco muestra los mensajes de error al enviar el formulario.
Descripción del Error
Cuando el dispositivo móvil no tiene acceso a conexión a internet, ciertas llamadas a la API REST hechas por la app resultan en IOException
y SocketException
que no son manejadas. Este problema ocurre para cualquier invocación a la API de sincronización de datos (perfil, configuración y datos).
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
La app debería manejar excepciones producidas por el cliente HTTP al intentar realizar peticiones sin conexión a internet. Sería bueno que la app notificara al usuario de estos problemas de sincronización.
Entorno
Contexto Adicional
Las invocaciones a la API que no manejan IOException
ni SocketException
son:
_updateProfileWithLocalChanges()
syncUpdatedHydrationGoalsWithAccount()
syncSettingsWithLocalChanges()
syncLocalActivityRecordsWithAccount()
Es importante arreglar estos problemas, y evitar hacer el mismo error cuando implemente la obtención de datos sincronizados.
Descripción del Error
El método Goal.parseTags()
asocia incorrectamente las etiquetas escritas por el usuario con las etiquetas creadas con anterioridad: cuando revisa la colección de etiquetas existentes para ver si contiene el valor de la etiqueta escrita, lo hace una sola vez con el primer carácter de la etiqueta que el usaurio está escribiendo. Esto hace que ninguna etiqueta escrita pueda asociarse con las etiquetas creadas.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Al crear una nueva meta que tiene una o varias etiquetas creadas con anterioridad, la meta debería hacer referencia a los registros existentes, en vez de volver a insertar las mismas etiquetas en la base de datos.
Entorno
Descripción del Error
El dropdown de país obtiene los países soportados desde la base de datos local. Si el código de país de una de las opciones es igual a "--", el texto de la opción queda como "Prefiero no especificar". El dropdown muestra más opciones de las que debería, como si en algún punto se estuvieran registrando nuevos países por defecto en la BD.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Esto solo debe pasar con el primero, que representa la opción de un país no especificado. Acciones en la base de datos no deberían modificar la tabla de países.
Entorno
Contexto Adicional
El problema posiblemente está relacionado con la base de datos y SQLiteDB
, porque fue observado tras realizar pruebas que insertaban perfiles vacíos en la base de datos. Hay un problema similar con las etiquetas de metas de hidratación.
Descripción del Error
El método _showGuidesDialog()
de MainView
produce una excepción no manejada al usar un contexto obsoleto (probablemente después de un async gap). Este error también es provocado por el método _showDialogIfReportAvailable()
.
Cómo Reproducir
Pasos para reproducir el error:
MainView
(como la vista de login o la de ajustes).MainView
Comportamiento Esperado
El método _showGuidesDialog()
debe mostrar, bajo ciertas condiciones, un AlertDialog
preguntando al usuario si desea consultar las guías de usuario online. No debería acceder a un BuildContext
obsoleto.
Entorno
Contexto Adicional
Mensaje de la excepción en la consola:
E/flutter (11861): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
E/flutter (11861): At this point the state of the widget's element tree is no longer stable.
E/flutter (11861): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
E/flutter (11861): #0 Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure>
package:flutter/…/widgets/framework.dart:4186
E/flutter (11861): #1 Element._debugCheckStateIsActiveForAncestorLookup
package:flutter/…/widgets/framework.dart:4200
E/flutter (11861): #2 Element.getElementForInheritedWidgetOfExactType
package:flutter/…/widgets/framework.dart:4226
E/flutter (11861): #3 Provider._inheritedElementOf
package:provider/src/provider.dart:339
E/flutter (11861): #4 Provider.of
package:provider/src/provider.dart:293
E/flutter (11861): #5 MainView._showGuidesDialog
package:hydrate_app/…/views/main_view.dart:27
E/flutter (11861): #6 MainView.build.<anonymous closure>
package:hydrate_app/…/views/main_view.dart:94
E/flutter (11861): #7 new Future.delayed.<anonymous closure> (dart:async/future.dart:423:39)
E/flutter (11861): #8 _rootRun (dart:async/zone.dart:1418:47)
E/flutter (11861): #9 _CustomZone.run (dart:async/zone.dart:1328:19)
E/flutter (11861): #10 _CustomZone.runGuarded (dart:async/zone.dart:1236:7)
E/flutter (11861): #11 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1276:23)
E/flutter (11861): #12 _rootRun (dart:async/zone.dart:1426:13)
E/flutter (11861): #13 _CustomZone.run (dart:async/zone.dart:1328:19)
E/flutter (11861): #14 _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1260:23)
E/flutter (11861): #15 Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
E/flutter (11861): #16 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
E/flutter (11861): #17 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
E/flutter (11861): #18 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
Descripción del Error
Durante pruebas de la app, he notado que el número de monedas mostrado por CoinDisplay
no es correcto; la mayoría de las veces es "3", un número poco común para haber sido obtenido como recompensa por hidratación o actividad.
Cómo Reproducir
Pasos para reproducir el error:
CoinDisplay
en su appbar superior, como las pestañas de inicio o perfil.Comportamiento Esperado
El widget debería mostrar una cantidad de monedas más normal, como 0, 50 o lo que haya conseguido el usuario por recompensas.
**Entorno **
v1.0.0-beta+1
Contexto Adicional
El widget CoinDisplay
obtiene el número de monedas del usuario al consumir el estado de ProfileProvider
. En el widget en sí no parece que haya problemas, entonces es probable que el problema sea 1 de 2 posibilidades:
ProfileProvider
o el modelo UserProfile
alteran el valor de profile.coins
.La funcionalidad que sugieres surgió de un problema? Por favor descríbelo.
La funcionalidad no surge de un problema o error en sí, sino que es una mejora para cumplir totalmente los requisitos y la especificación para la función de recomendación de hidratación. Por ahora, la implementación incluye varios de los factores, pero todavía es necesario hacerla más precisa, legible y luego optimizarla.
Describe la solución que te gustaría
Falta considerar ciertos factores al aproximar la ingesta de agua recomendada:
Descripción del Error.
Cuando la conexión a internet es interrumpida mientras la app está en proceso de hacer una petición HTTP, una ClientException
es lanzada y no es manejada con un try/catch.
Cómo Reproducir
Pasos para reproducir el error:
ClientException
que no es manejadoComportamiento Esperado
La app debería manejar con gracia las posibles excepciones producidas por causas externas (como una interrupción de conectividad). No debería crashear con ellas.
Entorno
Contexto Adicional
Por ejemplo, cuando el método ArticlesApi.fetchArticles()
es invocado para obtener los recursos informativos desde la API web y la conexión a internet es interrumpida durante la petición, la siguiente excepción es lanzada en la línea 34:
ClientException (Software caused connection abort)
Esto debería ser manejado cachando la excepción e indicando visualmente al usuario que los recursos informativos no pudieron ser obtenidos por falta de conexión a internet.
Cambiar el tipo de dato de los campos de 'Habits' para que sean doubles, REAL en SQLite.
Asociar los registros médicos con el perfil de usuario
Descripción del Error
Parece que con cada ejecución de la app, de alguna manera se agregan nuevos registros en la tabla muchos a muchos entre perfiles y entornos. Los registros son idénticos (referencian al mismo perfil de usuario y el mismo entorno). Esto provoca que métodos como UserProfile.selectedEnvironment
produzcan errores inesperados.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
La app agrega un solo registro a la tabla muchos a muchos, cuando se crea un nuevo perfil de usuario. Este registro referencia el nuevo perfil con el entorno por defecto (el entorno que es desbloqueado gratis, para todos).
**Entorno **
Contexto Adicional
El total de registros en la tabla debe equivaler a la suma del número de perfiles desbloqueados de cada perfil de la app.
También, el getter UserProfile.selectedEnvironment
produce un error cuando unlockedEnvironments
no está vacío, pero el ID de selectedEnvId
no coincide con ninguno de los entornos desbloqueados. Actualmente, esto genera un StateError
. Quizás es más apropiado que simplemente modifique selectedEnvId
a un valor correcto y retorne el entorno por defecto.
Descripción del Error
Si el usuario crea una meta de hidratación con una fecha de inicio del mismo día y luego registra uno o más consumos de agua ese mismo día, la barra de progreso de la meta no refleja la cantidad de agua ingerida en ese día.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Todas las metas deberían actualizar su progreso cada vez que la app registra un nuevo consumo de agua. Este cambio debe ser reflejado en la UI y en los datos internos (en la otorgación de recompensas, definición de metas sugeridas, etc.)
Entorno
Contexto Adicional
Revisar los rangos de fechas usados para obtener el progreso de una meta, en el método getGoalProgressInMl()
de HydrationRecordProvider
.
Descripción del Error
Parece que los dialog mostrados por ReportAvailableDialog
aparecen demasiadas veces, incluso cuando el usuario ya completó el formulario correspondiente. Además, los dialogs para formularios recurrentes y médicos aparecen al mismo tiempo, por lo que uno tapa al otro.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Los dialogs de ReportAvailableDialog
deberían ser mostrados una vez por apertura de la app cuando sea necesario, no "encimarse" uno sobre otro y deberían registrar que el usuario ya respondió el formulario.
**Entorno **
Descripción del Error
Cuando la app intenta sincronizar el perfil de usuario con su cuenta a través de la API REST de perfiles, obtiene un error 404 mencionando que "no existe un pais con el ID especificado".
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Si el usuario ha iniciado sesión y tiene un perfil asociado a su cuenta, cuando realiza modificaciones al perfil, los cambios deberían poder ser sincronizados con su cuenta a través de la API de perfiles (excepto cuando no tiene acceso a internet).
Entorno
Contexto Adicional
El mensaje de error mostrado es como el siguiente:
I/flutter ( 8840): Error al sincronizar cambios a perfil (ApiException:(requestError, status = 404) Request format is incorrect, details: "No existe un pais con el ID especificado")
Descripción del Error
Con los cambios para los resultados paginados de recursos informativos, se removieron los indicadores de error de carga de ArticleSliverList
y la app no hace aparente cuando no puede obtener los recursos porque no tiene conexión a internet.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
El widget debería mostrar indicadores de condiciones anormales, como errores de conexión, base de datos, servicio web inalcanzable.
**Entorno **
Contexto Adicional
Es probable que otras vistas como la de inicio de sesión necesiten indicadores más claros
Descripción del Error
Cuando el usuario intenta crear una nueva meta y le asigna fechas de inicio y fin, si el usuario vuelve a abrir el DatePicker
y presiona el botón "cancelar", la fecha respectiva toma un valor null
y no se incluye en el query para insertar la meta en la BD local. Esto produce un DatabaseException
.
Cómo Reproducir
Pasos para reproducir el error:
DatePicker
y presionar el botón "cancelar".Comportamiento Esperado
El usuario debería poder cancelar un DatePicker
sin "eliminar" el valor previo. Debe haber congruencia entre el modelo de Goal
y su esquema en la BD local (así como con su esquema de la API REST).
Entorno
Contexto Adicional
El error se repite infinitamente, como si la app siguiera intentando insertar la nueva meta indefinidamente.
Descripción del Error
Cuando el método SQLiteDB.insert()
crea los registros necesarios para describir una relación muchos a muchos usada por alguna entidad, parece que crea registros duplicados en la tabla muchos a muchos.
Cómo Reproducir
Pasos para reproducir el error:
perfil
, que se relaciona con varios entornos
)SQLiteDB.insert()
.Comportamiento Esperado
El método debería insertar sólo los registros necesarios en la tabla de relación muchos a muchos.
**Entorno **
La gráfica de kilocalorías quemadas por día en los últimos siete días muestra información correcta cuando los datos son de ActivityRecord
s directamente. Cuando hay registros de actividad que son producidos por una actividad rutinaria, las KCal de estos no son tomadas en cuenta para los totales.
La gráfica obtiene sus datos de ActivityProvider
, invocando su método _previousSevenDaysTotals()
. Posiblemente este método no ha sido actualizado para tomar en cuenta actividades rutinarias.
Descripción del Error
Cuando se modifica el valor del switch para activar/desactivar los formularios semanales, no aparece el snackbar de guardar cambios. Además, aún cuando se modifica otro valor y sí aparece la snackbar, al presionar "guardar" los cambios en la configuración de formularios semanales no son guardados.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Al cambiar el valor del switch de activación de formularios recurrentes, debería aparecer el snackbar de confirmación de cambios. Cuando se presiona el botón de "guardar" en el snackbar de confirmación, los cambios deben ser persistidos, para mantener su valor en reinicios o durante el uso de la app.
**Entorno **
El indicador de progreso lineal de todas las metas esta completado al 100% (su valor es 1.0). Es raro, dados los totales de los registros de hidratación de días pasados y los periodos de las metas.
getGoalsProgressValuesInMl()
y _totalsFromPrevDaysInMl()
en el debugger.Cuando se inserta un nuevo registro de una entidad que tiene una columna para el ID del perfil, la app lanza una excepción:
SqfliteDatabaseException (DatabaseException(table actividad has no column named perfil (code 1 SQLITE_ERROR[1]): , while compiling: INSERT INTO actividad (titulo, fecha, duracion, distancia, kilocalorias_quemadas, perfil, al_aire_libre, es_rutina, id_tipo_actividad) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?))
Lo más probable es que, debido a que MapOptions.includeCompleteSubEntities = true
, todas los atributos de la entidad que hagan referencia a otra entidad cambian su nombre de "id_otra_entidad" a "otra_entidad".
MapOptions
en SQLiteDB
sea consistente.Descripción del Error
Cuando se completa correctamente el formulario de creación de cuenta y se envía, produce un error de "credenciales incorrectas", a pesar de que las credenciales tengan formato correcto. Esto se debe a que el formulario tiene las credenciales de una cuenta existente. La indicación de error es poco clara y parece un error en sí.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
El formulario de creación de cuenta debería proporcionar un indicador de error más claro, sin comprometer la seguridad de una cuenta existente (e.g. no decir que el nombre de usuario ya está en uso).
Entorno
Descripción del Error
Creía que la función para compartir el progreso de hidratación en otras apps ya había sido implementada, pero parece que quedó perdida en una rama alterna o en el repositorio local perdido alrededor de mayo.
Comportamiento Esperado
La app debe permitir al usuario compartir su progreso en apps de redes sociales (Facebook y Twitter, principalmente).
Entorno
Descripción del Error
El constructor UserCredentials.forAction()
completa incorrectamente los atributos de la nueva instancia de UserCredentials
cuando authAction
es AuthActionType.signIn
y el valor del argumento username
no puede ser usado como e-mail. Esto resulta en que tanto username
y email
queden como Strings vacíos, en vez de simplemente usar el username
.
Cómo Reproducir
Pasos para reproducir el error:
UserCredentials.toMap()
lanza un ArgumentError
.Comportamiento Esperado
Cuando authAction
es para iniciar sesión, este método debería crear una instancia de credentials que use el valor del argumento username
como para el atributo email
solo cuando este valor tenga la forma de un email. Por el contrario, debe asignar el valor del argumento username
a su atributo username
.
Entorno
Descripción del Error
Cuando ProfileForm
es usado como formulario inicial, no muestra el campo para seleccionar la ocupación del usuario.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
ProfileForm
incluye un campo para seleccionar ocupación cuando es usado para la creación inicial de un perfil. ProfileForm
no muestra este campo cuando es usado para modificar un perfil existente.
**Entorno **
Contexto Adicional
Por este error, cuando se crea un nuevo perfil el valor asignado a la ocupación del perfil siempre es "sin especificar" (el valor por defecto)
Descripción del Error
Para los artículos producidos por la API web de recursos informativos, la app no puede hacer interpretar los publishDate
desde strings ISO 8601.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
La fecha de publicación de todos los artículos debería poder ser interpretada como un valor de string ISO 8601 y las tarjetas de recurso informativo deberían mostrar esa misma fecha.
**Entorno **
v1.0.0-beta+1
Contexto Adicional
El error está relacionado con inconsistencias en la representación de fechas en formato ISO 8601
entre la app y la API web.
Descripción del Error
La manera en que el método filtra los registros de actividad según fecha es poco coherente, hace falta revisar la forma en que determina los rangos de tiempo (usando includeToday
, considerando el cambio de horario,
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
El método _getActivitiesFromPastWeek()
debería hacer más clara la forma en que determina el rango de días considerado como "la semana pasada", o adoptar un modelo como _totalsFromPrevDaysInMl()
que es mucho más flexible.
Entorno
Descripción del Error
Cuando la app es desconectada de la extensión para botellas (usando el método disconnect()
de flutter_blue
), parece que sigue procesando eventos por un rato, invocando el método callback _onRecordAvailable
. Después de algunos momentos, los eventos dejan de producirse y la app vuelve a su estado normal.
Cómo Reproducir
Pasos para reproducir el error:
_onRecordAvailable
constantemente.Comportamiento Esperado
La app debería cancelar cualquier procesamiento de eventos para sincronizar registros de hidratación, cuando la extensión para botellas sea desconectada.
Entorno
Contexto Adicional
Logs de la app:
I/FlutterBluePlugin(27267): [onCharacteristicRead] uuid: 00000fff-0000-1000-8000-00805f9b34fb status: 0
I/flutter (27267): Date char bytes: [33, 0, 0, 0, 0, 0, 0, 0]
D/FlutterBluePlugin(27267): mDevices size: 1
I/flutter (27267): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 0faf892f-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
D/FlutterBluePlugin(27267): [onCharacteristicRead] uuid: 0faf892f-0000-1000-8000-00805f9b34fb status: 0
I/flutter (27267): Handling change on pendingRecordsCount: [1]
I/flutter (27267): A punto de tomar _gattLock
I/ViewRootImpl@87b963[MainActivity](27267): ViewPostIme pointer 0
I/ViewRootImpl@87b963[MainActivity](27267): ViewPostIme pointer 1
I/flutter (27267): Disconnecting from device
D/BluetoothGatt(27267): cancelOpen() - device: E0:E2:E6:9B:3B:C2
D/BluetoothGatt(27267): onClientConnectionState() - status=0 clientIf=13 device=E0:E2:E6:9B:3B:C2
D/FlutterBluePlugin(27267): [onConnectionStateChange] status: 0 newState: 0
D/BluetoothGatt(27267): close()
D/BluetoothGatt(27267): unregisterApp() - mClientIf=13
I/flutter (27267): Device state changed BluetoothDeviceState.disconnected
I/flutter (27267): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 00002a19-0000-1000-8000-00805f9b34fb serviceUuid: 0000180f-0000-1000-8000-00805f9b34fb
I/flutter (27267): Error al leer el valor de una caracteristica del servicio de bateria (UUID = 00002a19-0000-1000-8000-00805f9b34fb): PlatformException(read_characteristic_error, no instance of BluetoothGatt, have you connected first?, null, null)
I/flutter (27267): Battery char bytes: []
I/flutter (27267): Synchronized data through BLE: {cantidad: 200, temperatura: -5.0, fecha: 1969-12-31 18:00:33.000}
I/flutter (27267): Not all required attributes could be obtained, expected 4
I/flutter (27267): _gattLock tomado
I/flutter (27267): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 0faf892c-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
I/flutter (27267): Error al leer el valor de una caracteristica del servicio de hidratacion (UUID = 0faf892c-0000-1000-8000-00805f9b34fb): PlatformException(read_characteristic_error, no instance of BluetoothGatt, have you connected first?, null, null)
I/flutter (27267): Ml char bytes: []
I/flutter (27267): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 00002a6e-0000-1000-8000-00805f9b34fb serviceUuid: 000019f5-0000-1000-8000-00805f9b34fb
I/flutter (27267): Error al leer el valor de una caracteristica del servicio de hidratacion (UUID = 00002a6e-0000-1000-8000-00805f9b34fb): PlatformException(read_characteristic_error, no instance of BluetoothGatt, have you connected first?, null, null)
(......)
I/flutter (27267): Error al leer el valor de una caracteristica del servicio de hidratacion (UUID = 0faf892f-0000-1000-8000-00805f9b34fb): PlatformException(read_characteristic_error, no instance of BluetoothGatt, have you connected first?, null, null)
I/flutter (27267): remoteId: E0:E2:E6:9B:3B:C2 characteristicUuid: 00002a19-0000-1000-8000-00805f9b34fb serviceUuid: 0000180f-0000-1000-8000-00805f9b34fb
I/flutter (27267): Error al leer el valor de una caracteristica del servicio de bateria (UUID = 00002a19-0000-1000-8000-00805f9b34fb): PlatformException(read_characteristic_error, no instance of BluetoothGatt, have you connected first?, null, null)
I/flutter (27267): Battery char bytes: []
I/flutter (27267): Synchronized data through BLE: {}
I/flutter (27267): Not all required attributes could be obtained, expected 4
I/ViewRootImpl@87b963[MainActivity](27267): ViewPostIme pointer 0
I/ViewRootImpl@87b963[MainActivity](27267): ViewPostIme pointer 1
D/FlutterBluePlugin(27267): mDevices size: 0
Descripción del Error
Cuando el método SQLiteDB.select()
es invocado, con un solo elemento como argumento a where
y un valor nulo como argumento para unions
, el where es completamente ignorado. Esto se debe a la condición (where != null && whereUnions != null)
, que solo es evaluada a true
cuando se incluye al menos un elemento en unions
(usualmente, para usar múltiples where).
El problema es encontrado en la línea 168 de SQLiteDB.dart
:
final fullWhere = (where != null && whereUnions != null)
? MultiWhereClause.fromConditions(where, whereUnions)
: null;
Cómo Reproducir
Pasos para reproducir el error:
SQLiteDB.select()
que use un solo WhereClause
en su parámetro where
. Este error fue encontrado en el método ProfileProvider.findProfileLinkedToAccount()
.Comportamiento Esperado
El método SQLiteDB.select()
debería realizar el query a SQLite usando los argumentos where
proporcionados, para poder realizar queries selectivas.
Entorno
Descripción del Error
Cuando se introducen los datos de un ActivityRecord
en NewActivityForm
y se presiona el botón "Crear", la app redirige a la vista principal, pero al navegar a la pestaña de historial el nuevo registro no se muestra.
Cómo Reproducir
Pasos para reproducir el error:
ActivityRecord
.ValidationMessageBuilder
, con cada cambio en el formulario.Bad state: no element
en SQLiteDB.select()
, línea 214 de sqlite_db.dart
.Comportamiento Esperado
La app debería mostrar todos los ActivityRecord
en la pestaña de historial de actividad. Además, ValidationMessageBuilder
no debería recibir errores de validación de tipo NumericInputError.isNaN
cuando valida la duración, distancia o kilocalorías de un registro de actividad física, y menos si los valores del fomrulario son correctos.
**Entorno **
Contexto Adicional
Al parecer, este error solo ha sido observado en la versión release
de la app. En modo debug
no ha aparecido.
Los mensajes de error completos:
I/flutter ( 3002): Unhandled activity record duration validation message for error: NumericInputError.isNaN
I/flutter ( 3002): Unhandled activity record distance validation message for error: NumericInputError.isNaN
I/flutter ( 3002): Unhandled activity record kCal validation message for error: NumericInputError.isNaN
I/flutter ( 3002): Query result example: {id: 1, titulo: Paseo, fecha: 2022-08-25T14:04:00.000, duracion: 20, distancia: 1.6666666666666665, kilocalorias_quemadas: 80, al_aire_libre: 1, es_rutina: 0, id_tipo_actividad: 0, id_perfil: 0}
E/flutter ( 3002): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: Bad state: No element
E/flutter ( 3002): #0 ListMixin.firstWhere (dart:collection/list.dart:167)
E/flutter ( 3002): #1 SQLiteDB.select (package:hydrate_app/src/db/sqlite_db.dart:214)
E/flutter ( 3002): <asynchronous suspension>
E/flutter ( 3002): #2 ActivityProvider._queryActivityRecords (package:hydrate_app/src/provider/activity_provider.dart:151)
E/flutter ( 3002): <asynchronous suspension>
E/flutter ( 3002): #3 CacheState.refresh (package:hydrate_app/src/provider/cache_state.dart:126)
E/flutter ( 3002): <asynchronous suspension>
Descripción del Error
El formulario de creación de nueva cuenta no muestra un mensaje de error en el campo adecuado cuando el usuario introduce una confirmación de contraseña que no coincide con la contraseña previamente introducida.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
Debe aparecer un mensaje de error si la confirmación de contraseña no es idéntica a la contraseña. El estado del formulario debe cambiar de forma correspondiente (el botón de envío debe ser desactivado).
Entorno
Descripción del Error
Esto no es necesariamente un error. De todos modos, esta configuración fue introducida como workaround para solucionar problemas de flutter_blue
, sin considerar antes lo que implica desactivar la ofuscación, minimización y optimización de código en una build de release.
La configuración problemática en [nombre-del-proyecto]/android/app/build.gradle
es la siguiente:
buildTypes {
release {
shrinkResources false
minifyEnabled false
}
}
Comportamiento Esperado
La funcionalidad de BLE no debería sacrificar aspectos importantes de la build de release.
Entorno
Contexto Adicional
La guía oficial de Android sobre minimización de código. También encontré esta respuesta a una "solución" de StackOverflow. en ella, el autor describe que la solución dada tiene implicaciones más profundas y seguramente debe ser posible arreglar el problema de raíz, en vez de usar un workaround.
Descripción del Error
Cuando la app obtiene uno o más registros de hidratación desde la extensión, es común que un mismo registro de hidratación sea "creado" varias veces, haciendo que se muestren muchos registros idénticos.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
La app debe obtener cada registro de hidratación una sola vez, y guardar cada registro en su BD una sola vez.
Entorno
Contexto Adicional
No estoy seguro si el problema es causado por la app al obtener los registros, o por la extensión, que notifica más de una vez a la app con el mismo registro.
Descripción del Error
El botón para enviar el formulario de creación de nueva cuenta permanece desactivado, aún cuando la información introducida en los campos es válida.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
El usuario debería ser capaz de enviar el formulario de creación de nueva cuenta si los datos que introdujo en los campos son válidos. El botón debería estar desactivado cuando los datos estén incompletos o no sean válidos, y activarse cuando el usuario complete el formulario correctamente.
Entorno
Descripción del Error
Cuando WorkManager intenta ejecutar la tarea para realizar una contribución a datos abiertos, se produce un NoSuchMethodError
. Esto significa que WorkManager no tiene acceso al método designado para manejar sus callbacks, BackgroundTasks.callbackDispatcher()
.
Cómo Reproducir
Pasos para reproducir el error:
Comportamiento Esperado
El módulo que interactúa con WorkManager debería poder especificar una función que maneja los callbacks y ejecuta las tareas en segundo plano.
Entorno
Contexto Adicional
Probablemente la función usada para manejar callbacks debe ser de top level (no estática de una clase).
La excepción produce el siguiente output al ser producida en debug:
E/flutter (29114): [ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: NoSuchMethodError: No top-level getter 'callbackDispatcher' declared.
E/flutter (29114): Receiver: top-level
E/flutter (29114): Tried calling: callbackDispatcher, stack trace: #0 NoSuchMethodError._throwNew (dart:core-patch/errors_patch.dart:216:5)
E/flutter (29114):
E/flutter (29114): [ERROR:flutter/runtime/dart_isolate.cc(668)] Could not resolve main entrypoint function.
E/flutter (29114): [ERROR:flutter/runtime/dart_isolate.cc(167)] Could not run the run main Dart entrypoint.
E/flutter (29114): [ERROR:flutter/runtime/runtime_controller.cc(382)] Could not create root isolate.
E/flutter (29114): [ERROR:flutter/shell/common/shell.cc(600)] Could not launch engine with configuration.
Problema
Cuando una actividad es definida como rutina, los registros son agregados con las fechas correctas. El problema es que ActivitySliverList
, en su Builder
, usa RoutineActivities.allActivities
, que asigna correctamente los registros de actividad pero no especifica la fecha de cada uno. Entonces, cuando el builder solo referencia el ActivityRecord
con ID = 2, usa su misma fecha, aunque sea una repetición por rutina.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.