'Trigger background proccess while Database table has data android
So here is my problem. I am developing a chat application. When the user launches the app, server sends to the client batches of messageIds which are stored inside a room Database table.
@Entity(
tableName = "pendingMsg",
primaryKeys = [
"pending_msg_account_id",
"pending_msg_message_id"
]
)
data class PendingMessage(
@ColumnInfo(name = "pending_msg_account_id") val accountId: Int,
@ColumnInfo(name = "pending_msg_batch_id") val batchId: String,
@ColumnInfo(name = "pending_msg_message_id") val messageId: String
)
For example
Batch1 (batchId: "1112abab1a1a2b12a", accountId: 100, messageIds: ["1234", "5674", "6234"]
Batch2 (batchId: "c34234t45tyc45t2c", accountId: 100, messageIds: ["7727", "8223", "6226"]
That means, that i have to Download those MessageIds that are messages from accountId: 100. Same happens for every Account or every Group. So the PendingMessage table would look like this
100 1112abab1a1a2b12a 1234
100 1112abab1a1a2b12a 5674
100 1112abab1a1a2b12a 6234
100 c34234t45tyc45t2c 7727
100 c34234t45tyc45t2c 8223
100 c34234t45tyc45t2c 6226
So, since this Table has Data coming in from Server i want a Deamon to download the pending Messages from the server.
I tried to have a Query that returns LiveData and handle the result
@Query("""Select * from pendingMsg""")
fun getPendingMessages(): LiveData<List<PendingMessage>>
And inside a LifeCycleObserver class
class AppLifeCycleObserver(appContext: Context) : LifecycleObserver {
//
pendingMessageRepository.observeForever() { it: List<PendingMessage> ->
// Here i handle the messageIds
// handleMessageIds(it.map { pm -> pm.messageId })
}
}
So the first time that this will be triggered i will handle the messageIds that are currently in the Database, which are
1234,5674,6234,7727,8223,6226
Now, let's say that another batch comes in, and the already existed messageIds in the Table have not been received yet from server, although i have asked them.
Batch3 (batchId: "2c363645634b6346v", accountId: 100, messageIds: ["5223", "8842", "4993"]
This will be inserted since there is no violation on the PrimaryKey. So the data in the Table now will be
100 1112abab1a1a2b12a 1234
100 1112abab1a1a2b12a 5674
100 1112abab1a1a2b12a 6234
100 c34234t45tyc45t2c 7727
100 c34234t45tyc45t2c 8223
100 c34234t45tyc45t2c 6226
100 2c363645634b6346v 5223
100 2c363645634b6346v 8842
100 2c363645634b6346v 4993
The Observer function will be called again and the messageIds that i will get will be
1234,5674,6234,7727,8223,6226, 5223,8842,4993
However, we have already handled the first 6 messageIds from the triggered before! So i want to distinguish the new messageIds 5223,8842,4993 from the previous ones because i don't want to ask from the server the same messageIds.
Is there any approach that could handle every message only once? How would be a good approach to that problem?
Solution 1:[1]
Is there any approach that could handle every message only once?
From the App aspect, you already have this as the accountId/messageId has to be unique (implicitly due to the primary key). So when inserting, if you have onConflict = OnConflictStrategy.IGNORE, then it will be ignored (and the insert, if using the convenience @Insert, will return -1 as opposed to the rowid which would always be 1 or greater upon a successful insert).
- rowid, is a normally hidden column in every table that is not a virtual table or one defined using WITHOUT ROWID (in Room the WITHOUT ROWID clause is not an option and therefore every Room table has a rowid).
If you want the message not to be sent, then you would need to include an indicator, on the server, that it has been sent and very probably received (the latter requiring the App to report the receipt to the server).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | MikeT |
