I am trying to add an item to a user in my Firebase database but I keep getting a NullPointerException every time I try and access the location I want to write the data. This location does not yet exist (because I need to first write data to it); however, this was not a problem when adding a "userID" section and adding information underneath it, like so:
database = FirebaseDatabase.getInstance();
userReference = database.getReference("accounts");
DatabaseReference currentUserDB = userReference.child(user.getUid());
currentUserDB.child("name").setValue(name);
The above section of the code adds a key with the user ID and then adds the users name inside it. This is similar to what I want to do next.
What I would like to do is add a section called "item" and inside that add "first" with the value name. Like this .
Where the keys "item" and "first" don't exist until the user first clicks the button to run this code. This code should also work item "second" and so on.
database = FirebaseDatabase.getInstance();
DatabaseReference dbR = database.getReference("accounts").child(uid);
reference = dbR.child("item");
DatabaseReference databaseReference = reference.child("test");
databaseReference.child("name").setValue(name);
I get a NullPointerException at this line:
DatabaseReference databaseReference = reference.child("test");
and I'm not sure why.
I am sure this has been answered in some form because it seems so simple, but I haven't seen anywhere that discusses writing two keys to the database at once.
Any help appreciated. My apologies if this is a duplicate.
Cheers
Edit: I know what a NullPointerException is, i just don't know why I'm getting one in this instance. The two sets of code are very similar and I'm not sure why the second code set gives me an error.
You should write your code like this:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
reference.child("accounts")
.child("test")
.child("item")
.child("first")
.child("name")
.setValue(name);
If possible put your code here, it would help.
I think if "item" and "first" doesnt exist you can't use it as reference cause the node isnt there.
You need to use reference = dbR.setValue("item") first, and then you can use use as ref.
Related
Hello i want to know why is my program changing selectedDataEdited List when i only changing editTransactionList ?
var editTransactionList: MutableList<Transaction>? = mutableListOf()
var selectedDataEdited: List<Transaction>? = listOf()
editTransactionList = listTest as MutableList<Transaction>
selectedDataEdited = listTest
var position = 0
println("edit $editTransactionList")
println("select $selectedDataEdited")
editTransactionList.get(position).apply {
amount = 2000
name = "K"
}
println("edit $editTransactionList")
println("select $selectedDataEdited")
editTransactionList.get(position).apply {
amount = 3000
name = "Z"
}
println("edit $editTransactionList")
println("select $selectedDataEdited")
the output is
edit [Transaction(amount=1000, name=T, test=1)]
select [Transaction(amount=1000, name=T, test=1)]
edit [Transaction(amount=2000, name=K, test=1)]
select [Transaction(amount=2000, name=K, test=1)]
edit [Transaction(amount=3000, name=Z, test=1)]
select [Transaction(amount=3000, name=Z, test=1)]
Variables are basically references. When you store an object in a variable you actually say "when using this variable please refer to this object". So if you "store" the same object into 2 different variables, each of them still refers to that same object. Getting the object using the first variable, making changes to it, and then accessing the second variable, will still get you that changed object.
You will need to copy the list to prevent the unwanted behavior. Keep in mind though that you would probably need a deep copy. Simply calling toList() on it for example only makes a shallow copy, which means that even though it will be a different list, the objects inside it will still refer to the original.
It's hard to tell what would work without knowing what Transaction looks like. If Transaction is a data class then selectedDataEdited = listTest.map { it.copy() } might work. See this example https://pl.kotl.in/Q_o8pYXVs
KOTLIN Why when i changed a List it is also accidentally changing another list
Because you don't have "another" list. You only have one list.
When you do selectedDataEdited = listTest, you assign a second reference to the same list. If you want two separate lists, you must create them, possibly by cloning the original list.
Instead of using as MutableList use toMutableList:
editTransactionList = listTest.toMutableList()
It will make a copy of your list instead of passing a reference to the same list.
I have an app, where I try to implement a function that would allow to create posts like in facebook. So, I want to create recyclerview that would fetch a data and display it on the screen when the post is created.
How do I do this?
I've written a code for this. But I get an error that in EventRecyclerAdapter.java in 40th line of code .get(position) is called on null reference object.
https://github.com/garaanon/IACS Here you can see the .java file I am referencing
Your Else Condition will trigger when the Data is Null than why are you trying to get Description When it is Null.Remove the getDesc() from Else Condition will Remove Error.
I need some clear explanation with addChildEventListener and Query event binding.
I use firebase in my android app. In the onCreate() method of my activity, I create something like this...
fiDbQuery = fiDbRef.child("users").orderByChild("name");
fiDbQuery.addChildEventListener(// listener //);
... where fiDbQuery is a Query instance in the activity (global var) and fiDbRef is a DatabaseReference instance in the activity too, where I already set the initial value.
all is well, when activity first loaded, all the users data are loaded and shown. But then, I have some button to sort this data according to users field, either by email, age, name, etc.
and in those buttons onClickevent listener, I do something like this... (this one is the sort by age button)
fiDbQuery = fiDbRef.child("users").orderByChild("age");
... and I didn't provide the addChildEventListener function because it is already "added" on onCreate() method, right? The data aren't loaded, but if I add the addChildEventListener function it works again.
My question is, is it save to use multiple addChildEventListener into one Query, or is there any performance issues with that? All I want to accomplice is reusing the fiDbQuery instance without the need to add addChildEventListener every single time I modify the fiDbQuery.
Thank You for your help.
EDIT:
all those query I make use the exact same listener. Only one listener for all those query which populate a listView.
You don't need to add the addChildEventListener again. What you need to do, is to change the logic of your actions a little bit.
First define all your queries like this:
nameQuery = fiDbRef.child("users").orderByChild("name");
ageQuery = fiDbRef.child("users").orderByChild("age");
//and so on
To solve your problem, you only need to use an if else-if statement which sounds like this:
Query query;
if(nameButton.isClicked()) {
query = nameQuery;
} else if(ageButton.isClicked()) {
query = ageQuery;
}
query.addChildEventListener( // listener. //);
This means that according on which button the click was made, you are using the desired query. With this code, you just use the addChildEventListener once.
Hope it helps.
I have a node in Firebase getting continually updated with information from a logfile. The node is lines/ and each child of lines/ is from a post() so it has a unique ID.
When a client first loads, I want to be able to grab the last X number of entries. I expect I'll do this with once(). From then on, however, I want to use an on() with child_added so that I get all new data. However, child_added gets all data stored in the Firebase and, after the initial setup, only want the new stuff.
I see that I can add a limitToLast() on the on(), but, if I say limitToLast(1) and a flood of entries come in, will my app still get all the new entries? Is there some other way to do this?
You need to include a timestamp property and run a query.
// Get the current timestamp
var now = new Date().getTime();
// Create a query that orders by the timestamp
var query = ref.orderByChild('timestamp').startAt(now);
// Listen for the new children added from that point in time
query.on('child_added', function (snap) {
console.log(snap.val()
});
// When you add this new item it will fire off the query above
ref.push({
title: "hello",
timestamp: Firebase.ServerValue.TIMESTAMP
});
The Firebase SDK has methods for ordering, orderByChild() and methods for creating a range startAt(). When you combine the two you can limit what comes back from Firebase.
I think there is a problem in #David East's solution. He is using the local timestamp which may cause problem if the time is not accurate in client device. Here is my suggested solution (iOS Swift):
Using observeSingleEvent to get the complete data set
Then returned it in reversed order by reversed()
Get the last timestamp by for example data[0].timestamp
Using queryStarting for timestamp
self._dbref.queryOrdered(byChild: "timestamp").queryStarting(atValue: timestamp+1)
.observe(.childAdded, with: {
snapshot in
print(snapshot.value)
})
You have the right idea. child_added should be called only for the new nodes. Without source code it's hard to tell why you get all the data in your child_added event.
You can check the chat demo app to see how they load new chat messages. The use case sounds similar.
https://github.com/firebase/firechat/blob/master/src/js/firechat.js#L347
Here's temporary but quick solution:
// define a boolean
var bool = false;
// fetch the last child nodes from firebase database
ref.limitToLast(1).on("child_added", function(snap) {
if (bool) {
// all the existing child nodes are restricted to enter this area
doSomething(snap.val())
} else {
// set the boolean true to doSomething with newly added child nodes
bool = true;
}
});
Disadvantage: It will load all the child nodes.
Advantage: It will not process existing child nodes but just the newly added child nodes.
limitToLast(1) will do the work.
I am attaching a picture of my firebase database. I am at OPL and I want to go to its parent. Is there somekind of "GetParent()" kind of fuction, like "GetChildren" that can take me there?
To read the data from database, you need to set listeners at appropriate locations. These listeners provide values for one time as well as for updates with the methods onChildAdded() and onChildChanged().
For your case, you should attach a childListener on the ActionList by using the line
mDatabase.child('ActionList').addChildEventListener(listenerName);
Set up the onChildAdded() method of this listener which provides a snapshot. Traversing through the children from that snapshot using dataSnapshot.getChildren() and to get their values use this function child.getKey() method.