How to add a record into Firebase database? [duplicate] - android

This question already has answers here:
How to add new data in firebase android
(4 answers)
Closed 3 years ago.
In my application, I am able to take a screenshot from my cameras. Then I upload images to Firebase storage and get a download link. Now, I want to add this link to my database. I am able to do that by the following code:
fun storeImageUrlToFBDatabase(userId: String, cameraName: String, imageUrl: String) {
val map = mapOf(cameraName to imageUrl)
val ref = getFBDatabaseReference().getReference("users/$userId/images")
ref.setValue(map)
.addOnSuccessListener {
Logger.d("$FB_DATABASE_TAG, Write was successful, $it")
}
.addOnFailureListener {
Logger.e("$FB_DATABASE_TAG, Write failed: $it")
}
}
This is what Firebase shows:
However, the problem is the current item under images will be replaced by a new item I am pushing in. My expectation is something like this:
camera-streaming
users
userX
auth
token: "xxx"
userId: "xxxx"
images
image1: "url1"
image2: "url2"
image3: "url3"
image4: "url4"
But, what I get after each push/insert under images is having only one item/record. What is the problem?

You need to use key value to store the new links. This can be done in two ways:
Keep track of the current image sequence in the DB and then push the next value like:
val ref = getFBDatabaseReference().getReference("users/$userId/images");
//you need to find next xth image somehow
ref.child('imagex').setValue("map");
Just push the link to thee random key generated by DB:
val ref = getFBDatabaseReference().getReference("users/$userId/images");
val newRef = ref.push();
newRef.setValue("map");

Related

Saving user list data in android compose

So im trying to understand how data is saved on android. I am currently working on a simple notes app. How it currently works, is the user creates a new note, types whatever they want, and once they hit the back button that entry is saved in to a list. I am using compose viewmodel so the entries are saved up until the point the app is destroyed. what is the best way to save the list entries so they are pemenantly saved on the phone. This is also just a general question on how apps generally save user input data that is not saved in the cloud.
here is some example of the code.
data class NotesBlueprint(
val header: String,
val note: String,
val key: Int
)
data class NotesVars(
val header:String = "", <<<< instance of header and the note
val note: String = "" <<<<
var list: List<NotesBlueprint> = mutableListOf() <<< list that the Notes are saved in to
)
You can store the data on android via Shared Preference, Database, and Files. This storage overview guide gives the idea regarding different types of the storage system and how they are saved on android.
In your case, if you want to save notes which user has written, it would be better to go with the database.
Android provides the Room library for storing data in the local database. You can check out the guide here.

Read Map Values within Array Firestore Kotlin

I'm trying to retrieve and store the values within this Map in my Firestore. The way I have my Firestore set up is like so:
I've found a way to retrieve other fields within my Firestore database but when trying to access map values like so:
horsepowerTextView.text = result.data?.getValue("Horsepower").toString()
it crashes the application and gives me an error saying that "Key Horsepower is missing in the map".
Can you please tell me how I would be able to get the values within Cars?
The following picture shows Firestore layout and code:
I've tried this link (how to read mapped data from firestore in kotlin) but when creating the map it only retrieves the topmost variable in the document NOT a part of the Map which would be the values firstName and lastName:
I actually answered that question, but your use case is totally different than the linked one. Why? Simply because "Cars" is an array of maps (custom objects). If you only want to get the value of the "Horsepower" field, then simply use the following lines of code:
val db = Firebase.firestore
val usersRef = db.collection("users")
usersRef.document("TwbJb27eFL3HAS1xLhP1").get().addOnCompleteListener {
if (it.isSuccessful) {
val data = it.result.data
data?.let {
val cars = data["Cars"] as List<*>
for (car in cars) {
val carMap = car as Map<*, *>
val horsepower = carMap["Horsepower"]
Log.d(TAG, "$horsepower")
}
}
}
}
The result in the logcat will be:
120
If you want however to map the "Cars" array into a list of custom objects, then I recommend reading the following resource:
How to map an array of objects from Cloud Firestore to a List of objects?

How to Search a Firebase Firestore Data Base on Selected Month in android studio Kotlin Language

Firestore Database Accessing Code in Activitymain.xml
db.collection("billNo") // I think want to add some code here to get the data!!//
.get()
.addOnSuccessListener {
user.clear()
for (document in it) {
user.add(User(
document.id,
document.data.get("billNo").toString().toInt(),
document.data.get("date").toString(),
document.data.get("name").toString(),
document.data.get("amount").toString().toInt(),
document.data.get("payment").toString()
)
)
}
Database Structure
#Parcelize
data class User(
val id: String,
val billNo: Int,
val date: String,
val name: String,
val amount: Int,
var payment:String
) : Parcelable
I Add billNo, date, name, amount, paid_or_unpaid data into the FIREBASE DATABASE. So when I click on searching I want to get details of the selected month in the RecyclerView. All RecyclerView code and other things working perfectly fine. Only I want to retrieve the data of the selected month.
When I click on the Respective Month & Year in the Following Activity (Screenshot is provided below) I want to get the details of bills in the respective month from the FIREBASE FIRE STORE DATA Base. I tried a lot. but I can't find a solution. I'm doing my project on Android Studio with KOTLIN programming Language.
There is no LIKE operator in Firestore. So a query like this:
"SELECT * from tablename WHERE date LIKE %$month-$year%"
Is actually not possible. Because your "date" field is actually a String, when using small data sets you might consider using:
Is there a way to search sub string at Firestore?
Or you can try using the newly Firebase Extension announced at Google I/O 2021 called:
Search with Algolia
Or directly in code:
Is it possible to use Algolia query in FirestoreRecyclerOptions?
However, there are two workarounds that can be used to achieve the same result. The first one would be to create another field in your User object called "monthYear". This property will hold a different value than the "date" property. For instance, if your "date" property holds the value of "03-May-2021", "monthYear" property will only hold the value of "May-2021". That been said, the Query will look like this in Kotlin:
val rootRef = FirebaseFirestore.getInstance()
val queryByMonthYear = rootRef.collection("billNo").whereEqualTo("monthYear", "May-2021")
The second solution would be to change the type of the "date" from String to Timestamp. Please see below how you can add a Timestamp to Firestore:
How to add a Timestamp in Firestore with Android?
It's in Java but you can simply convert it in Kotlin. Then, you can use a Query with a call to startAt(startDate) and endAt(endDate).

Is there a better way of retriving Document Refernce?

I am new to Firestore and I am developing an android app where I am loading comments in Recycler View.
Below is sample data class for comment.
data class Comment(
val id: String,
val text: String,
val user: DocumentReference
)
Currently I am using this below code in onBindViewHolder in adapter
comment.userId.get()
.addOnCompleteListener {
if (it.isSuccessful) {
val u = it.result.toObject(User::class.java)
user = u.name
binding.userTv.text = user
}
}
binding.commentTv.text = comment.text
I have to explicitally run Task<TResult> every time to fetch the user in adapter.
I am looking for a better way to retrieve user from comment to display username is a single query.
Typically when dealing with usernames that may update regularly, traditionally you would store the raw user name string in each document which requires heavy read/writes to keep it updated. Instead, it has been found better to store them in a master document/collection that assigns all user UID's with the display name as the value, allowing you to look up any user UID and know it from one source of truth.
This has been made easier with the new Bundle Feature which allows all apps to preload documents in your app to prevent the need to fetch them every time. The only catch is you will need to retrieve the data when a new user isn't in their cached data yet or have a dedicated source for all new users to reduce overhead in those situations.
Source: Data Bundles

How to save user values without logging in and then add data fields in the current user value from some other activity?

I want to create a game app in android kotlin using firestore.When user first enters app he enters a "name" which I want to save in firestore.
When he submits name he is taken to next activity screen which has 2 options host n join.
If he clicks host he should enter the gameroomname and click host button.
On clicking host button the gameroom name should be stored along with the name entered on first screen for the particular current user.
I have stored username in firestore but I am not sure how can I find that same username and add gameroomname for the same user on my third screen.
How can I achieve doing this or what can I refer in order to do this?
I have added the skelton pictures of screens of the app below:
1)First screen where user enters username:
enter image description here
2)Second screen where user chooses host or join:
enter image description here
3)When user chooses host from second screen he lands on this screen:
enter image description here
Code i used to store username:
mFirestore= FirebaseFirestore.getInstance()
gamingSubmit.setOnClickListener(View.OnClickListener {
val gamingUserName:String=gamingName.text.toString()
val userMap=HashMap<String,Any>()
userMap.put("gamingName",gamingUserName)
mFirestore.collection("AllUsers").document("host").collection("hostids").document(gamingUserName).set(userMap)
.addOnSuccessListener(OnSuccessListener {
Toast.makeText(this#MainActivity,"Successfully submitted name",Toast.LENGTH_LONG).show()
}).addOnFailureListener(OnFailureListener {e->
val error=e.message Toast.makeText(this#MainActivity,"Error:"+error,
Toast.LENGTH_LONG).show()
})
If you already setup firestore in your project (if not you can use this guide), you only need to initialize the instance, something like:
// Access a Cloud Firestore instance from your Activity
val db = FirebaseFirestore.getInstance()
Then you can save the values using:
// Create a new user with a game room
val userRoom = HashMap<String, Any>()
userRoom["name"] = "Ada"
userRoom["gameroom"] = "Lovelace"
// Add a new document with a generated ID
db.collection("userRooms")
.add(userRoom)
.addOnSuccessListener { documentReference ->
Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.id)
}
.addOnFailureListener { e ->
Log.w(TAG, "Error adding document", e)
}
The above code will create a new document with that has two fields: a name and a gameroom. See here more details on how to manipulate data in firestore.

Categories

Resources