首页 > 解决方案 > 使用 Expo 构建的应用程序中不存在/未加载数据库

问题描述

在过去的几个月里,我一直在使用 react native 和 Expo 开发我的第一个应用程序项目。

我已准备好最终启动我的应用程序,但我遇到了一个大问题:该应用程序使用预制的 sqlite 数据库来读取和更新信息,该数据库在首次启动或版本已更新时被加载到应用程序中(通过一个简单的变量)。我通过 Expo Client 测试了该应用程序没有任何问题,但是现在我正在手机中(通过 apk)尝试它,没有数据库,我不知道为什么它不工作

这是加载数据库的代码:

FileSystem.downloadAsync(
  Asset.fromModule(require('../databases/programs.db')).uri,
  `${FileSystem.documentDirectory}SQLite/programs-${version}.db`
).then(() => {
  programsDB = SQLite.openDatabase(`programs-${version}.db`);
  loadDB(loaded);
});

我在 metro.config.js 中有这个:

module.exports = {
  resolver: {
    blacklistRE: blacklist([/amplify\/#current-cloud-backend\/.*/]),
    assetExts: ["db", "ttf", "png", "jpg"]
  },
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: false,
      },
    }),
  },
};

这在 app.json

"assetBundlePatterns": [
  "src/library/assets/**/*",
  "src/library/databases/*",
  "src/library/fonts/*"
],
"packagerOpts": {
  "assetExts": ["db"]
},

我都试过了

require('../databases/programs.db'

require('library/databases/programs.db'

在应用程序尝试从数据库加载内容后,我收到以下错误:“/data/user/0/com.company.myApp/files/SQLite/programs-2020052401.db 的目录不存在”

在我在别处阅读的答案后,我还尝试将源数据库从 .db 下载到 .mp4 ,但它也没有这样做。

有任何想法吗?这是我最终可以启动我的应用程序之前的最后一个障碍。

标签: androiddatabasesqlitereact-nativeexpo

解决方案


解决方案

在对其进行修补以隔离问题之后,我最终发现问题在于将要保存在设备中的数据库的目录(SQLite)不是使用 downloadAsync 创建的,如果我有的话我会知道的更仔细地阅读文档。如果目录不存在,我只需要先创建目录,然后它就可以正常工作了。

以下是编码最终的样子:

// Check if the directory where we are going to put the database exists
let dirInfo;
try {
    dirInfo = await FileSystem.getInfoAsync(`${FileSystem.documentDirectory}SQLite`);
} catch(err) { Sentry.captureException(err) };

if (!dirInfo.exists) {
  try {
    await FileSystem.makeDirectoryAsync(`${FileSystem.documentDirectory}SQLite`, { intermediates: true });
  } catch(err) { Sentry.captureException(err) }
};

// Downloads the db from the original file
// The db gets loaded as read only
FileSystem.downloadAsync(
  Asset.fromModule(require('../databases/programs.db')).uri,
    `${FileSystem.documentDirectory}SQLite/programs${version}.db`
  ).then(() => {
  programsDB = SQLite.openDatabase(`programs${version}.db`); // We open our downloaded db
  loadDB(loaded); // We load the db into the persist store
}).catch(err => Sentry.captureException(err));

推荐阅读