首页 > 数据库 >Flutter项目移动端SQLite升级指南:解决json_extract函数缺失问题

Flutter项目移动端SQLite升级指南:解决json_extract函数缺失问题

时间:2024-08-15 11:53:48浏览次数:14  
标签:SQLite sqlite id json extract payload

引言

在Flutter移动端项目中依赖于SQLite的高级功能(如json_extract),在低版本的Android系统上部署时,可能会遇到函数不支持的问题。本文将指导你如何通过升级项目中使用的SQLite版本来解决这一问题。

前置条件

Flutter项目使用sqflite: ^2.3.3+1进行SQLite数据库操作。
IMBoy APP具有C2C类型的消息表,其中payload字段存储JSON字符串。

需求背景

实现“查找聊天”记录功能,涉及到对JSON字段的搜索查询,需要使用json_extract函数。

SELECT auto_id, id, type, from_id, to_id, payload, created_at, is_author, topic_id, status, conversation_uk3 FROM message WHERE 1=1 AND (json_extract(payload, '$.text') LIKE '%abc%' or json_extract(payload, '$.quote_text') LIKE '%abc%' or json_extract(payload, '$.title') LIKE '%abc%') and conversation_uk3=? ORDER BY created_at desc LIMIT 10 OFFSET 0, (OS error - 2:No such file or directory)) sql 'SELECT auto_id, id, type, from_id, to_id, payload, created_at, is_author, topic_id, status, conversation_uk3 FROM message WHERE 1=1 AND (json_extract(payload, '$.text') LIKE '%abc%' or json_extract(payload, '$.quote_text') LIKE '%abc%' or json_extract(payload, '$.title') LIKE '%abc%') and conversation_uk3=?

问题描述

在低版本的Android系统上,SQLite数据库不支持json_extract函数,导致查询失败。
具体错误:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DatabaseException(no such function: json_extract (Sqlite code 1 SQLITE_ERROR): , while compiling: SELECT auto_id, id, type, from_id, to_id, payload, created_at, is_author, topic_id, status, conversation_uk3 FROM message WHERE 1=1 AND (json_extract(payload, '$.text') LIKE '%abc%' or json_extract(payload, '$.quote_text') LIKE '%abc%' or json_extract(payload, '$.title') LIKE '%abc%') and conversation_uk3=? ORDER BY created_at desc LIMIT 10 OFFSET 0, (OS error - 2:No such file or directory)) sql 'SELECT auto_id, id, type, from_id, to_id, payload, created_at, is_author, topic_id, status, conversation_uk3 FROM message WHERE 1=1 AND (json_extract(payload, '$.text') LIKE '%abc%' or json_extract(payload, '$.quote_text') LIKE '%abc%' or json_extract(payload, '$.title') LIKE '%abc%') and conversation_uk3=? ORDER BY created_at desc

问题分析

json1扩展需要SQLite版本至少为3.38.0。
sqflite使用平台自带的SQLite,版本比较低为 3.22.0。

解决方案

为Android版本添加最新版本的SQLite库,以支持json1扩展。

操作步骤

  1. 下载最新版本的SQLite AAR文件并校验其SHA3-256哈希值。

下载 https://sqlite.org/2024/sqlite-android-3460100.aar ,放入 ./android/app/lib/ 目录(如果目录不存在就创建之);
然后手动校验aar的 sha3-256

https://sqlite.org/2024/sqlite-android-3460100.aar

(SHA3-256: c3bec0e3a17349d3a7a6b9b7d9f23e4b14ae38a175469c28377cd1e7aa41f62c )

openssl dgst -sha3-256 /Users/leeyi/project/imboy.pub/imboyflutter/android/app/lib/sqlite-android-3460100.aar
  SHA3-256(/Users/leeyi/project/imboy.pub/imboyflutter/android/app/lib/sqlite-android-3460100.aar)= c3bec0e3a17349d3a7a6b9b7d9f23e4b14ae38a175469c28377cd1e7aa41f62c
  1. 在 ./android/app/build.gradle 文件中添加对SQLite AAR的依赖。
andriod {
    ...
    dependencies {
        ...
        // 添加sqlite的依赖
        implementation files('lib/sqlite-android-3460100.aar')
    }
}
  1. 在Flutter代码中初始化数据库,确保使用最新版本的SQLite。

在flutter代码中使用 sqlite-android-3460100.aar,不需要安装 依赖 sqflite_common_ffisqlite3_flutter_libs

我安装了最新版本的依赖(2024-08-15)

  sqflite: ^2.3.3+1
  sqflite_common_ffi: ^2.3.3
  sqlite3_flutter_libs: ^0.5.24

/Users/leeyi/project/imboy.pub/imboyflutter/lib/service/sqlite.dart
在dart源码中应用

  Future<Database?> _initDatabase() async {
    // Init ffi loader if needed.
    sqfliteFfiInit();
    ...
    String path = await dbPath();
    ...
    // debugPrint("> on open db path {$path}");
    return await databaseFactoryFfi.openDatabase(
      path,
      options: OpenDatabaseOptions(
        version: _dbVersion,
        onConfigure: _onConfigure,
        onCreate: _onCreate,
        onUpgrade: _onUpgrade,
        onDowngrade: _onDowngrade,
        readOnly: false,
        singleInstance: true,
      ), // 重新打开相同的文件是安全的,它会给你相同的数据库。
    );
  }

结果验证

  1. 在Android Studio里面真机调试,打印日志为:
andriod [ +225 ms] I/flutter (19060): iPrint SQLite version: [{sqlite_version(): 3.46.0}]
  Future<Database?> get db async {
    _db ??= await _initDatabase();

    // https://developer.android.com/reference/android/database/sqlite/package-summary
    // 查询 SQLite 版本
    final versionResult =
        await _db?.database.rawQuery('select sqlite_version();');
    if (versionResult!.isNotEmpty) {
      iPrint('SQLite version: $versionResult');
      // ios [  +55 ms] flutter: iPrint SQLite version: [{sqlite_version(): 3.46.1}]
      // andriod [ +225 ms] I/flutter (19060): iPrint SQLite version: [{sqlite_version(): 3.46.0}]
    }
    return _db;
  }
  1. 真机执行“查找聊天记录”也正常了

  2. 理论上应该要为3.46.1才对,是吧?

我也感觉困惑,针对这个问题,我在sqlite论坛发表了帖子,https://sqlite.org/forum/forumpost/03226f767e

不管怎么样,问题还是解决了

总结

通过升级项目使用的SQLite版本,我们成功解决了在低版本Android系统上json_extract函数缺失的问题,保证了APP功能的完整性和稳定性。

唯一的缺点是 APP的打包体检有增加了 3.6M (sqlite-android-3460100.aar 还有3.6M)了,不过还是值得的.

参考资料:

  • https://github.com/tekartik/sqflite/blob/master/sqflite/doc/troubleshooting.md
  • https://sqlite.org/android/doc/trunk/www/index.wiki 《SQLite Android 绑定》
  • https://github.com/tekartik/sqflite/tree/master/sqflite_common_ffi#readme
  • https://developer.android.com/reference/android/database/sqlite/package-summary

标签:SQLite,sqlite,id,json,extract,payload
From: https://blog.csdn.net/leeyisoft/article/details/141218849

相关文章

  • C#基础:JSON和字符串、字典、实体类的相互转化方案
    备注:可直接在控制台输出,不需要引用第三方nuget包usingSystem;usingSystem.Collections.Generic;usingSystem.Text.Encodings.Web;usingSystem.Text.Json;classProgram{publicclassData{publicstringMoCategorySelect{get;set;}......
  • gdb 查看 jsoncpp对象
    jsoncpp是c++使用较多的json库,gdb调试时,不方便查看json对象的信息,这里提供一种方法。json::value利用map实现树状对象,map的类型为std::maps<Json::Value::CZString, Json::Value>unionValueHolder{LargestIntint_;LargestUIntuint_;doublereal_;boolbo......
  • .Net Core appsettings.json详解 (多环境配置)
    前言在实际开发中一般分为开发环境与生产环境,不同环境下部分配置会有所不同,例如数据库连接字符串等。.NetCore框架中提供了三个值,Development(开发),Staging(分阶段),Production(生产环境),可以根据这三个值配置不同环境。创建appsettings文件创建项目时系统默认创建appsettin......
  • @DateTimeFormat 和 @JsonFormat 注解详解
    目录一、快速入门1.1准备工作1.2、入参格式化(前端传参到后端)1.3、出参格式化(后端返回给前端)1.4、如果是请求体@RequestBody传参二、详细解释这两个注解1、@JsonFormat2、@DateTimeFormat注意:1、这两者的注解一般联合使用2、注意2参考链接一、快速入门先说总结:如果......
  • 25.python模块(加密,os,re,json)
    一.加密讲解加密算法:md5\rsa\AES\des\base(一)base64加解密importbase64a=base64.b64encode(b"123456")print(a)#加密#b'MTIzNDU2'b=base64.b64decode(b'MTIzNDU2')print(b)#b'123456'http://encode.chahuo.com/在线加解密hashlib......
  • pbootcms网站是使用sqlite数据库好还是使用mysql数据库好?
    众多周知pbootcms程序支持sqlite数据库和mysql数据库,目前默认常用最多的是sqlite数据库,有需要转成mysql数据库的可以联系我们。pbootcms数据库sqlite无缝转换mysql数据库 本人从接触pbootcms开始一直都是使用mysql数据库,很少出现被黑和各种不明原因报错。建议有条件的朋友尽量......
  • 【待做】【WEB安全】浅谈JSONP劫持漏洞
    一、JSONP二、JSONP劫持示例三、JSONP劫持绕过方法3.1Referer过滤(常规)不严格3.2空引用绕过3.3回调可以定义引起的安全问题3.4测试HTML代码四、JSONP修复JSONPJSONP的全称是JSONwithPadding,是一种基于JSON格式来解决跨域请求资源的方案。由于......
  • Json中使用中文作为key的风险
    编码问题不同的系统和编程语言可能使用不同的字符编码(如UTF-8、GBK等),这可能导致解析时出现乱码。在传输过程中,如果编码没有正确指定,也可能导致乱码。兼容性问题并非所有的编程语言和库都支持使用中文作为键名。一些JSON处理库可能没有明确地声明是否支持中文键名,......
  • 第17天 信息打点-语言框架&开发组件&FastJson&Shiro&Log4j&SpringBoot等
    时间轴演示案例指纹识别—本地工具—GotoScanPython—开发框架—Django&FlaskPHP—开发框架—ThinkPHP&Laravel&YiiJava—框架组件—FastJson&Shiro&Solr&Spring知识点1.CMS指纹识别—不出网程序识别解决:CMS识别到后前期漏洞利用和代码审计一般PHP开发居多,利用源码......
  • Unity 配置 SQLite
    原Github仓库链接:https://github.com/robertohuertasm/SQLite4Unity3d?tab=readme-ov-fileAllyouhavetodotostartusingitinyourproject:Downloadthiszip,extractitscontentand copytheresultingfoldertoyourAssets/Pluginsfolder.Itcontainsthe......