Search code examples
androidandroid-sqliteandroid-contentproviderandroid-multiple-users

Use separate DB for each app user, with SQLiteOpenHelper and a ContentProvider


My app uses an SQLite DB, wrapped with a SQLiteOpenHelper and a ContentProvider. I added a sign-in feature to the app, and now I want every user to only be able to see his own data. The way I thought to achieve this is for the app to create a separate DB for every user that signs in to the app, and use the user's ID in the filename of the database.

I have this ContentProvider:

public class MyProvider extends ContentProvider {

    //...

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

I have this SQLiteOpenHelper:

public class MyDBHelper extends SQLiteOpenHelper {

Which has this constructor:

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

Up until now the app couldn't have multiple users, so it just had one database. so DB_NAME was always the same String. I now tried to set it like that:

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

(As you can see, I'm using Firebase Authentication)

but this resulted in a crash, because apparently the content provider is created on app start, before the user has authenticated. (so user is null. Yeah, I should check that user is not null before I try to call getUid(). but this won't make this thing work)

So this doesn't seem like the right approach. How can I use a different DB according to the signed user? Can I make the content provider to first be created after a user has authenticated?

I could also just keep everything in one database and add a UID column. But will this be protect the different users' data good enough from each other? Also, this would mean a lot more code changes.


Solution

  • How can I use a different DB according to the signed user?

    The simple solution is to get rid of the ContentProvider. The only reason to use a ContentProvider is if you are going to be serving this data to other apps.

    Also, I would be wary of just taking getUid() and putting it in a filename. You are not in control over what getUid() returns, and it might someday contain characters that are invalid in filenames.

    Can I make the content provider to first be created after a user has authenticated?

    No, sorry.