I have a data class where I retrieve Firebase information. It looks similar to this:
#IgnoreExtraProperties
data class EventData(var eventEmoji: String = "",
var PlanType: PlanType = PlanType.CUSTOM_TYPE_1,
var accel: Boolean = false,
var latitude: String = "0.0",
var longitude: String = "0.0",
var initialDate: String = "",
var finalDate: String = "",
var initialHour: String = "",
var finalHour: String = "",
var plae: String = "",
var addr: String = "",
var description: String = "",
var adminProfileImageUrl: String = "") : Serializable
The problem that I'm facing now, is that exist a new data information that before was unused.
But this new field can exist or not depending on Business people. That field contains some translations, but... not always are the same or same number of it.
Example how is in Firebase:
The problem is that I don't know how to retrieve all this data in the EventData class.
I tried to add the new attribute as:
var localizable: Map<Any,Any>? = hashMapOf()
var localizable: Map<String,Any>? = hashMapOf()
var localizable: Map<String,String>? = hashMapOf()
var localizable: Map<String,SpecificClass>? = hashMapOf()
But... doesn't work.
Is possible to achieve?
Related
I'm Firebase new here and I'm trying to retrieve the nested data from firebase. I have spent the whole day but can't deal with it.
this is my object structures
data class Punch(
var roundID: Int = 0,
var isCorrect: Boolean = true,
var speed: Double = 0.0
)
data class Training(
var sessionID: String = "",
var userId: String = "",
var username: String = "",
var date: Date = Date(),
var round_Sessions: MutableList<RoundInfor>
)
data class RoundInfor(
var roundID: String = "",
var round_length: Double = 0.0,
var total_punches: Int = 0,
var correct_punches: Int = 0,
var incorrect_punches: Int = 0,
var avg_heart_rate: Double = 0.0,
var avg_speed: Double = 0.0,
var punches: MutableList<Punch>
)
My data structure
For example: I'm trying to save data from round_Sessions and punches. How could I dig into this?
I'm trying to pass a map from Firestore into a data class but I'm getting null instead of the data
This is how my data is accessed:
firestoreDb = FirebaseFirestore.getInstance()
val postsRef = firestoreDb
.collection("posts")
.limit(20)
.orderBy("creation_time_ms", Query.Direction.DESCENDING)
.orderBy("date", Query.Direction.DESCENDING)
postsRef.addSnapshotListener { snapshot, exception ->
if (exception != null || snapshot == null) {
Log.e(TAG,"Exception when querying post", exception )
return#addSnapshotListener
}
val postList = snapshot.toObjects(HousePost::class.java)
for (post in postList) {
Log.i(TAG, "Posts $post")
}
}
My model for the data
data class HousePost (
#get:PropertyName("image_url") #set:PropertyName("image_url") var postImage: String = "",
var rent: String = "",
var description: String = "",
#get:PropertyName("creation_time_ms") #set:PropertyName("creation_time_ms") var creationTimeMs: Long = 0L,
var location: String = "",
#get:PropertyName("post_id") #set:PropertyName("post_id")var postId: String? = "",
var rooms: String = "",
var caption: String = "",
var date: String = "",
var owner: Owner? = null
)
My Owner model class
class Owner(
var uid: String = "",
var username: String = "",
var email: String = "",
#get:PropertyName("profile_image") #set:PropertyName("profile_image") var profileImage: String = "",
#get:PropertyName("user_type") #set:PropertyName("user_type")var usertype: String = "owner"
)
Here is my firestore data I know some fields are an empty string but that shouldn't output null.
This is the result from logcat
2022-05-03 11:42:12.313 6581-6581/com.example.moveapplication I/MainActivity: Posts HousePost(postImage=https://firebasestorage.googleapis.com/v0/b/moveapplicationdb.appspot.com/o/Post%20Pictures%2Fian-dooley-_-JR5TxKNSo-unsplash.jpg?alt=media&token=6721ec57-7602-41ee-b7cd-b8b1838b27fc, rent=15000, description=Along Ngong road we have a studio room for you to rent. Located in a moder =n area with nice infrastrucure, creationTimeMs=1651561930185, location=Lenana, postId=, rooms=studio room, caption=studio room along Ngong road, date=03/05/2022, owner=null)
My index from firestore
Looking at your class definitions, all look fine. You're using the correct annotations. However, when you're using the following query:
val postsRef = firestoreDb
.collection("posts")
.limit(20)
You'll need to know that you have to create an index. It can be manually created inside the Firebase Console or if you are using Android Studio, you'll find a message in the logcat that sounds like this:
FAILED_PRECONDITION: The query requires an index. You can create it here: ...
Simply click on that link or copy and paste the URL into a web browser and your index will be created automatically for you.
Following SQLite query (with room database library) returning null result. Which is incorrect, as you can see in the attached image.
#Query("SELECT * FROM REPOSITORY_DATABASE_TABLE WHERE item_category LIKE :key")
fun getItemByCategory(key: String) : LiveData<List<Item>>?
#Query("SELECT * FROM REPOSITORY_DATABASE_TABLE WHERE item_storage_type = :key ORDER BY item_name")
fun getItemByCategories(key: String) : LiveData<List<Item>>?
where other queries as follow returning correct result in running application as well as in Android Debug Database
#Query("SELECT * FROM REPOSITORY_DATABASE_TABLE ORDER BY item_name")
fun getAllItems() : LiveData<List<Item>>
Item Data structure:
#Entity(tableName = ApplicationConstants.REPOSITORY_DATABASE_TABLE_NAME)
data class Item(
#PrimaryKey(autoGenerate = false) #SerializedName("item_id")
var itemID: Long = 0L,
#ColumnInfo(name = "item_guid") #SerializedName("item_guid")
var itemGUID: String = "0",
#ColumnInfo(name = "item_name") #SerializedName("item_name")
var itemName: String = "Mango",
#ColumnInfo(name = "item_category") #SerializedName("item_category")
var itemCategory: String = "Fruit",
#ColumnInfo(name = "item_weight") #SerializedName("item_weight")
var itemWeight: Int = 0,
#ColumnInfo(name = "item_count") #SerializedName("item_count")
var itemCount: Int = 1,
#ColumnInfo(name = "item_image") #SerializedName("item_image")
var itemImage: String = "https://stackoverflow.com/questions/62131564/a-failure-occurred-while-
executing-org-jetbrains-kotlin-gradle-internal-kaptexec",
#ColumnInfo(name = "item_notes") #SerializedName("item_notes")
var itemNotes: String = "Sweet Yellow Mango",
#ColumnInfo(name = "item_display_quantity") #SerializedName("item_display_quantity")
var itemDisplayQuantity: String = "0",
#ColumnInfo(name = "item_storage_type") #SerializedName("item_storage_type")
var itemStorageType: String = "0",
#ColumnInfo(name = "item_creation_date") #SerializedName("item_creation_date")
var itemCreationDate: String = "0",
#ColumnInfo(name = "item_is_checked") #SerializedName("item_is_checked")
var itemIsChecked: String = "0",
#ColumnInfo(name = "item_local_status") #SerializedName("item_local_status")
var itemLocalStatus: String = "0",
#ColumnInfo(name = "item_last_added") #SerializedName("item_last_added")
var itemLastAdded: String = "0",
#ColumnInfo(name = "item_notification_status") #SerializedName("item_notification_status")
var itemNotificationStatus: String = "0",
#ColumnInfo(name = "item_priority") #SerializedName("item_priority")
var itemPriority: String = "0",
#ColumnInfo(name = "item_notification_days") #SerializedName("item_notification_days")
var itemNotificationDays: Int = 1,
#ColumnInfo(name = "item_expiry") #SerializedName("item_expiry")
var itemExpiry: String = "0",
#ColumnInfo(name = "item_synonyms") #SerializedName("item_synonyms")
#TypeConverters(Converters::class)
var itemSynonyms: List<String> = listOf("0","0")
)
Also while debugging the database with Android Debug Database I am getting correct response as shown in following image
Android Debug Database Screenshot showing correct response
Try removing the null safety operator from the return type of the query like this:
fun getItemByCategory(key: String) : LiveData<List<Item>>
And you don't have to use #SerializedName() if the SerializedName name is going to be the same as the variable itself.
And also it is very recommended if you use #PrimaryKey(autoGenerate = True) instead of false. Otherwise, you have to manually update the PrimaryKey every time you modify your table.
Can't see how to do this and getting rather confused!
I am saving 'site' objects to firestore, but I want to add a list of users associated to each site.
I have added a Map of users to my JSON object as below:
#IgnoreExtraProperties
data class SiteObject(
var siteReference: String,
var siteAddress: String,
var sitePhoneNumber: String,
var siteEmail: String,
var invoiceAddress: String,
var invoicePhoneNumber: String,
var invoiceEmail: String,
var website: String,
var companyNumber: String,
var vatNumber: String,
var recentProjectsText: String,
//not set up yet:
var sitePriority: Boolean,
var siteRating: Int,
var plusCode: String,
var users: Map<String, Boolean>?, // This is the map I have added
#ServerTimestamp
var dateCreatedTimestamp: Date?,
#ServerTimestamp
var dateEditedTimestamp: Date?,
#Exclude
var siteID: String?
) : Serializable {
private constructor() : this(
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
false,
1,
"",
null,
null,
null,
null
)
override fun toString(): String {
return "$siteReference"
}
}
And in my respository I am trying to add the current user to this list of users as below:
// save sites to firebase
fun saveSite(site: SiteObject) {
site.users?.plus(Pair(firebaseUser?.uid.toString(), true)) // This is where I expected the user Id to be added to Map of users..
val documentReference = firestore.collection("sites").document().set(site)
.addOnCompleteListener {
if(it.isSuccessful){
Log.d(TAG, "${site.toString()} saved")
lastOperationText.value = "New site, ${site.siteReference}, saved!"
} else {
Log.d(TAG, "${site.toString()} saved")
lastOperationText.value = "Save new site failed"
}
}
}
However, I still seeing null for users in the Firestore console.
Your code never gives an initial value to users. It starts off null. Since it doesn't get assigned a value, this code will not make a change to it, because it's first checking to see if users is null using the ?. operator:
site.users?.plus(Pair(firebaseUser?.uid.toString(), true))
You will need to assign it an initial value before trying to modify it. It should probably never be null and just start empty.
var users = HashMap<String, Boolean>()
For completeness, below is my updated data class. This initialises the values when it is created and also includes #Exclude #set:Exclude #get:Exclude on siteID to prevent this being saved to Firestore (used to store generated id when read from Firestore):
#IgnoreExtraProperties
data class SiteObject(
var siteReference: String = "",
var siteAddress: String = "",
var sitePhoneNumber: String = "",
var siteEmail: String = "",
var invoiceAddress: String = "",
var invoicePhoneNumber: String = "",
var invoiceEmail: String = "",
var website: String = "",
var companyNumber: String = "",
var vatNumber: String = "",
var recentProjectsText: String = "",
var sitePriority: Boolean = false,
var siteRating: Int = 1,
var plusCode: String = "",
var users: HashMap<String, Boolean> = hashMapOf(),
#ServerTimestamp
var dateCreatedTimestamp: Date? = null,
#ServerTimestamp
var dateEditedTimestamp: Date? = null,
#Exclude #set:Exclude #get:Exclude
var siteID: String = ""
) : Serializable {
override fun toString(): String {
return "$siteReference, $siteAddress, $siteRating, $siteID"
}
fun siteDetailsText(): String {
var siteDetailsText = siteAddress
if (sitePhoneNumber.isNotEmpty()) siteDetailsText.plus("\n\n$sitePhoneNumber")
if (website.isNotEmpty()) siteDetailsText.plus("\n\n$website")
return siteDetailsText
}
fun invoiceDetailsText(): String {
var invoiceDetailsText = invoiceAddress
if (invoicePhoneNumber.isNotEmpty()) invoiceDetailsText.plus("\n\n$invoicePhoneNumber")
if (companyNumber.isNotEmpty()) invoiceDetailsText.plus("\n\n$companyNumber")
if (vatNumber.isNotEmpty()) invoiceDetailsText.plus("\n\n$vatNumber")
return invoiceDetailsText
}
}
I m having a databaseView code like this.
#DatabaseView("SELECT * FROM Product")
data class ProductDatabaseView(
var productCode: String? = "",
var productName: String? = "",
var longDescription: String? = "",
var productUom: String? = "",
var customerCode: String? = "",
var price: String? = ""
)
And I wanna pass some value as we do in our DAO like this.
#DatabaseView("SELECT * FROM Product WHERE priceListCode = :priceListCode")
data class ProductDatabaseView(
var productCode: String? = "",
var productName: String? = "",
var longDescription: String? = "",
var productUom: String? = "",
var customerCode: String? = "",
var price: String? = ""
)
Is it able to pass value like this or is there any other option available with the help of View.
To my knowledge, no you can't pass argument to #DatabaseView. They work the same way as in sqlite which doesn't allow parameters in views.