通过SQLiteOpenHelper和ContentProvider为每个应用程序用户使用单独的数据库

时间:2018-07-07 17:20:42

标签: android android-sqlite android-contentprovider android-multiple-users

我的应用程序使用SQLite数据库,并用SQLiteOpenHelperContentProvider包装。我在应用程序中添加了登录功能,现在我希望每个用户只能看到自己的数据。我认为实现此目标的方法是,为应用程序创建一个用于登录该应用程序的单独的数据库,并在数据库文件名中使用该用户的ID。

我有这个ContentProvider

public class MyProvider extends ContentProvider {

    //...

    @Override
    public boolean onCreate() {
    dbHelper = new MyDBHelper(getContext());
    return true;
}

我有这个SQLiteOpenHelper

public class MyDBHelper extends SQLiteOpenHelper {

具有以下构造函数:

public MyDBHelper(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
}

到目前为止,该应用程序不能有多个用户,因此它只有一个数据库。因此DB_NAME始终是相同的字符串。我现在尝试将其设置为:

private static String UID = FirebaseAuth.getInstance().getCurrentUser().getUid();
public static final String DB_NAME = String.format("data%s.db", UID);

(如您所见,我正在使用Firebase身份验证)

但这导致崩溃,因为显然是在用户验证之前在应用启动时创建了内容提供程序。 (所以user为空。是的,在尝试调用user之前,我应该检查getUid()是否为空。但这不会使此事情正常工作

因此,这似乎不是正确的方法。如何根据已签名的用户使用其他数据库?我可以让内容提供者在用户验证后首先创建吗?

我还可以将所有内容保存在一个数据库中,并添加一个UID列。但这是否可以保护彼此之间的数据足够好呢?另外,这将意味着更多的代码更改。

2 个答案:

答案 0 :(得分:0)

  

如何根据已签名的用户使用其他数据库?

简单的解决方案是摆脱CreateFile.ps1。使用ContentProvider的唯一原因是是否要将这些数据提供给其他应用。

此外,我会警惕只取ContentProvider并将其放在文件名中。您无法控制getUid()的返回值,有朝一日它可能包含文件名中无效的字符。

  

我可以使用户首先通过身份验证后创建内容提供程序吗?

不,对不起。

答案 1 :(得分:0)

似乎正确的解决方案是不使用ContentProvider。所以我接受了另一个答案。

但是要回答我的实际问题,对于确定要使不同的DB与一个ContentProvider 一起工作的人们,可以这样做:

我将自定义SQLiteOpenDBHelper的构造函数更改为也采用了uid

    public MyDBHelper(Context context, String uid) {
        super(context, String.format(DB_NAME, uid), null, DB_VERSION);
        UID = uid;
    }

,并且我更改了onCreate中的ContentProvider,而不创建了DBHelper。我创建了以下用于初始化DBHelper的函数:

    public void initDB(Uri uri) {
        String uid = uri.getPathSegments().get(0);
        if (dbHelper == null){
            dbHelper = new MyDBHelper(getContext(), uid);
        } else if (!uid.equals(dbHelper.UID)){
            dbHelper.close();
            dbHelper = new MyDBHelper(getContext(), uid);
        }
    }

我在queryinsertupdatedelete方法的开头调用此方法。

因此,只要内容提供者对数据库执行了某些操作,但与数据库尚未建立连接,或者与数据库建立了连接,则DBHelper会保持与数据库的开放连接其他用户的数据库。

这不是解决此问题的正确方法,在某些情况下可能会产生后果。但是我不想让我的问题没有得到回答。