NullPointer exeption when retrieving data from Firebase database - android

I try to retrive data from firebase database
but i have null pointer exeption
here is my model code
class Request {
var Name: String? = null
var Phone: String? = null
var Street: String? = null
var Home:String?= null
var Flat:String?=null
var Status: String?=null
}
Here is how i retrieve data
var mDatabase=FirebaseDatabase.getInstance().reference
mDatabase.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onDataChange(p0: DataSnapshot) {
for (d in p0.children) {
var modelRequest: Request? = d.child("Requests").child(user.toString()).getValue(Request::class.java)
var ord: Order? =d.child("Orders").getValue(Order::class.java)
Log.d("loadedList", "ok")
requestList.add(modelRequest!!)
}
}
})
Here is my data structure

You're looking over the top-level nodes in your database (Food, Requests, etc) and then getting the Requests child node of each. Since there is no /Requests/Requests that will always be null.
This should be closer:
override fun onDataChange(snapshot: DataSnapshot) {
var modelRequest: Request? = snapshot.child("Requests").child(user.toString()).getValue(Request::class.java)
var ord: Order? =snapshot.child("Orders").getValue(Order::class.java)
Log.d("loadedList", "ok")
requestList.add(modelRequest!!)
}
Note that you're now loading all the data from your database, to then only use the Requests and Orders nodes. This is a waste of bandwidth, so you really should only request the data you need. You could do this by attaching two listeners and waiting for the result of both.

Related

Get firebase snapshot data in Kotlin Android

I'm new to Android & I don't know how to get all the firebase snapshot data at once inside the UID in the single data class.
val usersPrivateRef = Constants.FIREBASE_RESIDENT_PRIVATE
usersPrivateRef?.child("Fs0qczU3GsfJuGDGAeEN7bIgfjD3")
?.addListenerForSingleValueEvent(object : ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()) {
println(snapshot)
} else {
showLongToast("Snapshot not exists")
}
}
override fun onCancelled(error: DatabaseError) {}
})
To get a value from the DataSnapshot you can use its child() and getValue calls. For example, to print Krishna's email, you'd do:
println(snapshot.child("personalDetails/email").getValue(String::class.java)
I have found a solution for my above question
With the help of Gson library & also I have created the Kotlin data classes same as my snapshot data.
private var residentDATA : ArrayList<MineUserInfo> = ArrayList<MineUserInfo>()
var gson = Gson()
val json = Gson().toJson(snapshot.value)
var data = gson?.fromJson(json, MineUserInfo::class.java)
residentDATA.add(data)

Can't convert object of type java.lang.Long to type(Model class); Fetching Data from firebaseDatabase android kotlin

I am using Firebase Database to populate a recyclerview. and i'm facing problem in fetching data.
the error
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type com.massino.pfeadelramzi.models.Meuble
my code:
var mdatabase : DatabaseReference?=null
var listMeubles = mutableListOf<Meuble>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_liste_meuble3_d)
mdatabase = FirebaseDatabase.getInstance().reference.child("Bureau")
mdatabase!!.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
for (sna: DataSnapshot in snapshot.children){
val lis: Meuble? = sna.getValue(Meuble::class.java) //THE PROBLEME IS HERE
listMeubles.add(lis!!)
}
mon_recycler.setHasFixedSize(true)
mon_recycler.layoutManager = LinearLayoutManager(this#ListeMeuble3DActivity)
mon_recycler.adapter = MeubleAdapter(listMeubles.toTypedArray()){}
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
}
My data Class Meuble:
data class Meuble(val imageResource: Int, val nom: String, val prix: Int,val stock:Int)
my Firebase data (now i'm just trying to find a solution so i created just one child
Code to add data to Firebase
button4.setOnClickListener{
var nomUI = spinner.selectedItem.toString()
var prixUI = textView2.text.toString().toInt()
var stockUI= textView3.text.toString().toInt()
var databaseref = firebaseDatabase.getReference(nomUI)
if ( nomUI != null || !TextUtils.isEmpty(prixUI.toString()) || !TextUtils.isEmpty(stockUI.toString())){
var meuble = Meuble(R.drawable.fauteuille2,nomUI,prixUI,stockUI)
databaseref.setValue(meuble)
}else {
Toast.makeText(this,"Remplissez la case manquante",Toast.LENGTH_LONG).show()
}
}
Please help to solve this exception.
As Ticherhaz commented: since you only have the properties for one child nodes under /Bureau, you should use loop over the child nodes in onDataChange.
Right now your loop means that sna points to each individual property, and that's why it fails. There is (for example) no way to parse the value of prix into a `` object.
The code for when you have a single child is:
mdatabase = FirebaseDatabase.getInstance().reference.child("Bureau")
mdatabase!!.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val lis: Meuble? = snapshot.getValue(Meuble::class.java)
listMeubles.add(lis!!)
mon_recycler.setHasFixedSize(true)
mon_recycler.layoutManager = LinearLayoutManager(this#ListeMeuble3DActivity)
mon_recycler.adapter = MeubleAdapter(listMeubles.toTypedArray()){}
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
Error Handling :
So to handle my error:
i had to add a Default Value to each parametre in the constructor of my Data class :
data class Meuble(val imageResource: Int = -1, val nom: String="", val prix: Int=-1,val stock:Int=-1)

How to retrieve nested data structure from Firebase Realtime Database on Kotlin

I'm trying to retrieve submittedRequests from database .
userRef.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(snapshot: DataSnapshot) {
if(snapshot!!.exists()){
val children=snapshot!!.children
for(item in children) {
val retrieveUser= item.getValue(User::class.java) //it crashes here
if (retrieveUser != null) {
userData.add(retrieveUser)
}
}
}
}
})
User Class
class User(val userId:String="", val name:String="", val surname:String="", val profileImageUrl: String="",val submittedRequests:String="", val pickedUpRequests:String="")
Error Message is :
com.google.firebase.database.DatabaseException: Failed to convert value of type java.util.HashMap to String
How can I retrieve submittedRequests from database properly?
You're declared submittedRequests:String="" in your User class. Looking at your JSON the submittedRequests is not a simple string, but rather a nested object, or a map.
This should work better
submittedRequests:Map<String, Any>=hashMapOf<String, Any>()

Populating Data Class via Simple Firebase Calls

Running into an error I have been researching and attempting to fix for the past couple weeks. There are tons of suggestions out there and I've tried at least half a dozen with the same result each time.
How does Kotlin access Firebase data and populate a very simple data class?
Error: com.google.firebase.database.DatabaseException:
Can't convert object of type java.lang.String to type com.touchtapapp.handsofhope.LandingTextTitles
Read about suggestions to first convert to a Map and then to my custom data class... attempted this, successfully created the Mapped values w/ correct data... but ran into the exact same error when sending the Mapped values to the customs data class (LandingTextTitles).
Current code:
Data Model Class
data class LandingTextTitles(
val subTitle: String,
val title: String
)
Method to retrieve data from firebase
private fun initTitles() {
val ref = FirebaseDatabase.getInstance().getReference("/landing")
ref.addListenerForSingleValueEvent(object: ValueEventListener {
override fun onDataChange(p0: DataSnapshot) {
p0.children.forEach {
val titles = it.getValue(LandingTextTitles::class.java)
}
}
override fun onCancelled(p0: DatabaseError) {
// Handle Cancelled Data
}
})
// Log the titles value to see if data passed correctly
Log.d("Titles", titles.toString())
}
When I log out something like Log.d(it.toString()), I see the keys and values just fine. What am I doing wrong here?
EDIT:
Firebase data snapshot
EDIT 2:
If we use Log.d("Titles", it.toString()), we get the following:
D/Titles: DataSnapshot { key = subTitle, value = Start Here. }
D/Titles: DataSnapshot { key = title, value = Facing unexpected problems? }
If you have the following database:
landing
randomId
subTitle : "Awesome"
title : "Developer Team"
Then you can retrieve title and subTitle by doing the following:
private fun initTitles() {
val ref = FirebaseDatabase.getInstance().getReference("/landing")
ref.addListenerForSingleValueEvent(object: ValueEventListener {
override fun onDataChange(p0: DataSnapshot) {
p0.children.forEach {
val title = it.child("title").getValue(String::class.java)
val subTitle = it.child("subTitle").getValue(String::class.java)
}
}
override fun onCancelled(p0: DatabaseError) {
// Handle Cancelled Data
}
})
// Log the titles value to see if data passed correctly
Log.d("Titles", titles.toString())
}
If you want to use the data class, then change this:
override fun onDataChange(p0: DataSnapshot) {
p0.children.forEach {
val titles = it.getValue(LandingTextTitles::class.java)
}
into this:
override fun onDataChange(p0: DataSnapshot) {
val titles = p0.getValue(LandingTextTitles::class.java)
}

load posts from firebase

i m working over application connected with fire base here which retrieves data from db 'm getting error unresolved reference dataSnapshot in Homefrag.kt file and to be very precise in
//load posts from firebase
fun LoadPostFromFireBase(){...}
clean project=>rebuild=>invalidate cache
fun LoadPostFromFireBase(){
myRef.child("posts")
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(p0: DataSnapshot ) {
try {
listOfPost.clear()
listOfPost.add(Post("0","him","url"," ","add","addPost"))
var td= dataSnapshot!!.value as HashMap<String,Any>
for(key in td.keys){
var post= td[key] as HashMap<String,Any>
listOfPost.add(Post(key,
post["postText"] as String,
post["postImageURL"] as String
,post["postDate"] as String
,post["personName"] as String
,post["personID"] as String))
}
adapter!!.notifyDataSetChanged()
}catch (ex:Exception){}
}
override fun onCancelled(p0: DatabaseError) {
}
})
}
getting unresolved dataSnapshot!
You're looking for something that does not exist. Look at what the function onDataChange is giving you through its parameters.
I don't know Kotlin, but I'm pretty sure looking at your syntax that you're receiving "p0" inside the onDataChange, but you're looking for the object dataSnapshot.
You can fix it by replacing
var td= dataSnapshot!!.value as HashMap<String,Any>
with
var td= p0!!.value as HashMap<String,Any>

Categories

Resources