我的应用程序使用SQLite数据库,用SQLiteOpenHelper
和ContentProvider
包装。我向应用程序添加了登录功能,现在我希望每个用户只能看到自己的数据。我认为实现此目的的方法是让应用程序为每个登录到应用程序的用户创建一个单独的数据库,并在数据库的文件名中使用用户的 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
为空。是的,在我尝试调用getUid()
之前,我应该检查user
是否为空。但这不会使这件事起作用(
所以这似乎不是正确的方法。如何根据已签名用户使用不同的数据库?是否可以在用户进行身份验证后首先创建内容提供程序?
我也可以将所有内容保存在一个数据库中并添加一个UID
列。但是,这会保护不同用户的数据吗?此外,这意味着更多的代码更改。
签名用户使用不同的数据库?
简单的解决方案是摆脱ContentProvider
。使用ContentProvider
的唯一原因是,如果您要将此数据提供给其他应用程序。
另外,我会谨慎地只取getUid()
并将其放在文件名中。您无法控制getUid()
返回的内容,并且有一天它可能包含文件名中无效的字符。
是否可以在用户进行身份验证后首先创建内容提供程序?
不,对不起。
似乎这里的正确解决方案是不使用ContentProvider
s。所以我接受了另一个答案。
但是要回答我的实际问题,对于决心使不同的数据库与一个ContentProvider
一起工作的人,这是如何做到的:
我更改了自定义SQLiteOpenDBHelper
的构造函数,也采用uid
:
public MyDBHelper(Context context, String uid) {
super(context, String.format(DB_NAME, uid), null, DB_VERSION);
UID = uid;
}
我更改了ContentProvider
的onCreate
,以不创建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);
}
}
我在query
、insert
、update
和delete
方法的开头称这种方法。
因此,每当内容提供程序在数据库上执行某些操作,但尚未与数据库建立现有连接,或者连接与其他用户的数据库连接时,都会初始化与数据库的打开连接的DBHelper
。
这不是解决此问题的正确方法,在某些情况下可能会产生后果。但我不想让我提出的问题得不到回答。