Ad

Check If An Entry Is Already In A Livedata List Wihout Looping Through The List

I am trying to build an app to help me track some of the tasks we have to do in the game.

I have a Firebase Firestore database that store all the tasks and I download at the application launch the data and add only the one I don't have. Here is my entry model:

@Entity(tableName = "entry_table")
data class Entry(
    @PrimaryKey(autoGenerate = true) var uid: Long?,

    @ColumnInfo(name = "title") val title: String,
    @ColumnInfo(name = "description") val description: String,
    @ColumnInfo(name = "target") val target: Int = 0,
    @ColumnInfo(name = "position") val position: Int = 0,
    @ColumnInfo(name = "starred") val starred: Boolean = false

) {
    constructor(): this(null, "", "", 0, 0, starred = false)
}

Since I download the document from the firestore database I cannot set an ID before inserting the entries in my SQLite database. This means that I cannot use the "contains" method on my livedata list (since the entries I recieve has a "null" id and the one from the database has an id). I need to loop though all the data, here is the code:

@WorkerThread
suspend fun insertEntry(entry: Entry) {
    for (doc in entriesList.value!!){
        if (doc.description == entry.description && doc.title == entry.title) {
            Log.d("MAIN_AC", "Entry already saved $entry")
            return
        }
    }
    entryDAO.insertEntry(entry)
}

My code works but I am not satisfied with it, is there a better way to make this happen? I was hoping that the contains method could ignore some arguments (in my case the autogenerated ID)

Ad

Answer

One way you can go about, assuming you are using Room, it is to annotate your insert function (in the relevant DAO) with OnConflictStrategy.IGNORE.

e.g.

@Dao
interface EntryDao {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(list: List<Entry>)
    // or (if you want the inserted IDs)    
    // fun insert(list: List<Entry>) : LongArray
}   

Be sure to also annotate your entity with the relevant unique index.

e.g.

@Entity(tableName = "entry_table",
    indices = [Index(value = ["title", "description"], unique = true)]
       )
data class Entry(
    @PrimaryKey(autoGenerate = true) var uid: Long,
    @ColumnInfo(name = "title") val title: String,
    @ColumnInfo(name = "description") val description: String
    //...
                )

Primary keys should not be null-able, you can .map to Entry wit uid = 0. If you are using the same entity model both locally and remotely that is probably not the best idea.

Ad
source: stackoverflow.com
Ad