I have spinner and i want to add key value from firebase to set on spinner list .I use code below but not working for me.
I want to add keys value(2015-16,2016-17,2017-18) in spinner.
Here my code it's not working.
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("First").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final List<String> sess = new ArrayList<String>();
for (DataSnapshot areaSnapshot: dataSnapshot.getChildren()) {
String Session = areaSnapshot.getKey();
sess.add(Session);
}
Spinner spinner = (Spinner) findViewById(R.id.spinner3);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(AdminMain.this, android.R.layout.simple_spinner_item, sess);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You're listening one level too high in your JSON tree. Your onDataChange() is now triggered with the CIVIL node, while you likely want it one level lower.
rootRef.child("First/CIVIL").addValueEventListener(
One thing to note though: this will load all data under each date, just to show that date in the spinner. If that is a significant amount of data, you're wasting your user's bandwidth.
I'd consider in that case flattening your data structure and keeping a separate node with just the dates:
"Dates": {
"CIVIL": {
"2015-16": true,
"2016-17": true,
"2017-18": true
}
}
The true values are just needed to make sure Firebase doesn't delete the keys. Downloading this branch of the JSON ensures you only download the minimum data that is needed to populate the spinner.
Related
I require help in implementing data from a secondary Firebase database into autocomplete TextViews in my android application. I have a database containing data on cars (Make of car, model of car, engine size).
I have attached an image displaying how my data is set in the database.
Database image
I would like to have one TextView that will only display all the "make" attributes, another TextView to display only "model" attributes depending on which "make of car" the user picked. (eg. if the user picks Audi, models displayed would be A4, A6, A3 only. if the user picks Volkswagen, models displayed would be Golf, Jetta, Passat only) and then the final TextView to display only the "engine size" that corresponds to the chosen "make" and "model" as each model of car has different engine sizes.
Any help would be greatly appreciated as I have been stuck on this element of my app for several weeks now and have tried countless different approaches.
Below is my class and code. The application runs with no errors but will not retrieve the data from the database.
public class VehicleSpec extends AppCompatActivity
{
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Sets the layout according to the XML file
setContentView(R.layout.activity_vehicle_spec);
//FirebaseDatabase database = FirebaseDatabase.getInstance();
//
FirebaseOptions options = new FirebaseOptions.Builder()
.setApplicationId("com.example.user.vel")
.setApiKey("AIzaSyBvBtL81H7aiUK90c3QfVccoU1CowKrmAA")
.setDatabaseUrl("https://finalyearproject-vel1-aac42.firebaseio.com/")
.build();
//
FirebaseApp.initializeApp(this, options, "secondary");
//
FirebaseApp app = FirebaseApp.getInstance("secondary");
FirebaseDatabase database2 = FirebaseDatabase.getInstance(app);
DatabaseReference dbref = database2.getReference();
DatabaseReference dbref2 = database2.getReference();
DatabaseReference dbref3 = database2.getReference();
//
dbref.child("Cars").addValueEventListener(new ValueEventListener()
{
public void onDataChange(DataSnapshot dataSnapshot)
{
final List<String> Cars = new ArrayList<String>();
for ( DataSnapshot suggestionSnap : dataSnapshot.getChildren() )
{
String suggestion = suggestionSnap.child("Make").getValue(String.class);
Cars.add(suggestion);
}//End For()
//XML TextView variable
AutoCompleteTextView actv = (AutoCompleteTextView) findViewById(R.id.auto);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(VehicleSpec.this, android.R.layout.simple_list_item_1, Cars);
actv.setAdapter(adapter);
}//End onDataChange()
public void onCancelled(DatabaseError databaseError)
{
}//End onCancelled()
});//End dbref ValueEventListener()
//
dbref2.child("Cars").addValueEventListener(new ValueEventListener()
{
public void onDataChange(DataSnapshot dataSnapshot)
{
final List<String> Cars = new ArrayList<String>();
for ( DataSnapshot suggestionSnap : dataSnapshot.getChildren() )
{
String suggestion = suggestionSnap.child("Model").getValue(String.class);
Cars.add(suggestion);
}//End for()
//XML TextView variable
AutoCompleteTextView actv1 = (AutoCompleteTextView) findViewById(R.id.auto1);
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(VehicleSpec.this, android.R.layout.simple_list_item_1, Cars);
actv1.setAdapter(adapter1);
}//End onDataChange()
public void onCancelled(DatabaseError databaseError)
{
}//End onCancelled()
});//End dbref2 ValueEventListener()
//
dbref3.child("Cars").addValueEventListener(new ValueEventListener()
{
public void onDataChange(DataSnapshot dataSnapshot)
{
final List<String> Cars = new ArrayList<String>();
for (DataSnapshot suggestionSnap : dataSnapshot.getChildren())
{
String suggestion = suggestionSnap.child("Engine Size").getValue(String.class);
Cars.add(suggestion);
}//End for()
//XML TextView variable
AutoCompleteTextView actv2 = (AutoCompleteTextView) findViewById(R.id.auto2);
ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(VehicleSpec.this, android.R.layout.simple_list_item_1, Cars);
actv2.setAdapter(adapter2);
}//End onDataChange()
public void onCancelled(DatabaseError databaseError)
{
}//End onCancelled()
});//End dbref3 ValueEventListener()
}//End onCreate()
I Don't really understand exactly what are you trying to achieve, but let's assume you want one of the followings:
Display a list of cars in a list with 3 sections , Make , Model and a drop down list for Engine Size:
i Suggest using RecyclerView with 2 TextViews (1 for Make, and the second for Model) and an AppCompatSpinner that will be populated from the Engine Size node. You can use these Libraries as your adapter :
FirebaseUI
Infinite-Fire i personaly like this one because it has a built in loadMore when you reach last the item.
Display a list of car Brands (Make in this case) and when a user selects an item, an other list with Models and Engine Sizes Appears : i Suggest using RecyclerView with A TextViews for Make and when the user clicks an item, you save the item name in your SharedPrefrances and open a new activity that displays only models from the selected Make using Firebase databaseRef.child("Cars").orderByChild("Make").equalesTo(getSelectedMake());
or just display them in an AlertDialog instead with a costume layout using the same methods...for displaying DATA You can use the above Libraries as well.
if This isn't what are you looking for , please explain your problem with details and i will update my answer.
Edit : using SharedPreferences to save a reference of the item is nonsense, it's a result of my low experience with android, instead you can use intent.putExtra()
Example
//Start your activity like this
intent.putExtra("itemId", itemId)
startService(intent)
//On your new activity's onCreate() get the itemId as the following
String itemId = intent.getStringExtra("itemId")
Item item = firebaseRef.child("cars")....getValue(Item:class)
I am trying to populate a spinner with values from my firebase database.
fdatabase = database.getReference();
fdatabase.child("SPORTS").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final List<String> Sports = new ArrayList<String>();
for (DataSnapshot snapshot:dataSnapshot.getChildren()) {
String SportName = dataSnapshot.child("SportName").getValue(String.class);
Sports.add(SportName);
}
Spinner spinner = (Spinner) findViewById(R.id.SportSpinner1);
ArrayAdapter<String> SportAdapter = new ArrayAdapter<String>(RegComplete.this, android.R.layout.simple_spinner_item, Sports);
SportAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(SportAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Here is the code and i'll share a snapshot of my database as well. Please help.
I tried your peace of code and modified the child names to get a value of my own database and it worked, so my guess is, that your code does not fit to your data structure.
But it's hard to help you, if you don't provide us your data structure. You try to get the value of
yourDatabase/"SPORTS"/"Sportname"
But I bet, you are missing a key in between and you actually meant this:
yourDatabase/"SPORTS"/SOME MISSING KEY/"Sportname"
So, try to changed this line
String SportName = dataSnapshot.child("SportName").getValue(String.class);
into this:
String SportName = dataSnapshot.child(**MISSING KEY**).child("SportName").getValue(String.class);
My data is being retrieved, but I only want to display the names in my spinner like URL_xxx_NB or URL_xxx_FR, because I'm storing different URLs when people use the app in another language, and I need to retrieve only the names and when I put datasnapshot.getvalue() it brings me the whole thing, name + link. See below.
This is what I'm doing:
mDatabase.child("Users").child(uid).child("URL_ArchivosUsuario").addValueEventListener(new ValueEventListener() {
final List<String> areas = new ArrayList<String>();
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.e("UserUrls",""+dataSnapshot);
areas.add(dataSnapshot.getValue().toString());
Spinner areaSpinner = findViewById(R.id.spinner);
ArrayAdapter<String> areasAdapter = new ArrayAdapter<String>(UserEdit.this, android.R.layout.simple_spinner_item, areas);
areasAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
areaSpinner.setAdapter(areasAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
My database structure:
And this is what my spinner is showing:
I only want to see in my spinner the different URL_xxx_fr, nb etc names, and then I can manage when the user clicks in the different URLs to do something
Solved it, i just needed to getChildren and getKey, this is what i have done after onDataChange:
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.getKey();
areas.add(name);
}
I am currently creating an app which logs a 6-digit int id's (values) and the time/date they were logged (keys) in a real-time database. I am trying to create a separate app to accompany this by listing the database key-value as items on a list, with a search query to search the id's.
My question is, how I should go about retrieving and listing both the keys and values as items in my listView? The items need to add themselves in real-time as well, so they can be viewed as they would in the Firebase console. Thanks!
public ArrayList<String> arr;
public ArrayAdapter adapter;
#Override
protected void onStart() {
super.onStart();
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
arr = new ArrayList<>();
ValueEventListener listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
map2list((Map) dataSnapshot.getValue());
//formats the datasnapshot entries to strings
adapter.notifyDataSetChanged();
//makes the ListView realtime
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
System.out.println(databaseError.toException());
// ...
}
};
mDatabase.addValueEventListener(listener);
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, arr);
ListView listView = (ListView) findViewById(R.id.yourOwnListView);
listView.setAdapter(adapter);
}
public void map2list(Map<String,Long> map){
arr.clear();
for (Map.Entry<String, Long> entry : map.entrySet()) {
Long key = Long.parseLong(entry.getKey());
String d = DateFormat.getDateTimeInstance().format(key);
Long value = entry.getValue();
arr.add(d + ": " + value);
}
}
I tested this on my own database and it works.
map2list() is my quick way of formatting your data for the listview. The best way to do this is with a custom arrayadapter or baseadapter, but that involves alot more code than you need for this example.
Be advised that keeping your keys as time is a bad idea since you could have a collision if two logs are made at the same time.
Lastly, firebase uses Longs over ints, so i used Longs for less code
I'm new to Firebase and NoSQL. I have an Android Demo, with a City Autocomplete Text Field in which I want to populate the cities I have from my Firebase DB, while typing.
{ "cities":{
"Guayaquil":true,
"Gualaceo":true,
"Quito":true,
"Quevedo":true,
"Cuenca":true,
"Loja":true,
"Ibarra":true,
"Manta":true
}
}
This is what I have so far.
How can I retrieve from the DB cities that start with a letter (input from keyboard)? If I start typing "G", I want to receive "Guayaquil" and "Gualaceo".
If I use orderByValue always returns an empty snapshot.
If I use orderByKey return the whole list.
Query citiesQuery = databaseRef.child("cities").startAt(input).orderByValue();
citiesQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> cities = new ArrayList<String>();
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
cities.add(postSnapshot.getValue().toString());
}
Note: If you can recommend a better data structure, you're welcome.
#NicholasChen has identified the problem. But here's the way you'd implement using the 3.x SDK:
DatabaseReference cities = databaseRef.child("cities")
Query citiesQuery = cities.orderByKey().startAt(input).endAt(input+"\uf8ff");
citiesQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> cities = new ArrayList<String>();
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
cities.add(postSnapshot.getValue().toString());
}
By starting at the user input and ending at the last string that starts with the user input, you get all matching items
For relatively short lists of items Ryan's approach will also work fine. But the above Firebase query will filter server-side.
Update
I just ran this code:
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference("39714936");
String input = "G";
DatabaseReference cities = databaseRef.child("cities");
Query citiesQuery = cities.orderByKey().startAt(input).endAt(input + "\uf8ff");
citiesQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> cities = new ArrayList<String>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
cities.add(postSnapshot.getValue().toString());
}
System.out.println(cities);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
And it printed:
true
true
So clearly matches two cities.
Feel free to test against my database: https://stackoverflow.firebaseio.com/39714936
Try something like this to iterate over the children in the cities snapshot and add all the cities to an ArrayList of Strings.
ArrayList<String> cityList = new ArrayList<>();
databaseRef.child("cities").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
cityList.clear();
for (DataSnapshot data : dataSnapshot.getChildren()){
cityList.add(data.getKey);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
// ...
}
});
Editing this paragraph for clarity:
This will get all your cities read into the program memory so you can use that data to display the cities to the user. If the city list changes, so will the data the user sees. If the user is not online, this will not work. This puts a real time, online only listener on the database.
The logic in my mind is something like:
Set a value listener on the text box.
When user types, make a view display all the items in the array list
that start with the same substring that was typed.
Handle arrayIndex errors of course.
Hopefully this will get you on the right track. I am sure there are other ways you could implement it but this is what I would personally do. If you need help with the code to display the correct cities, start a chat with me and I can brainstorm with you.
Of course OrderByValue returns nothing because that's the booleans you have.
you can use the startAt and endAt methods to do so. (The below is Firebase 2.0's Code)
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByKey().startAt("b").endAt("b\uf8ff").on("child_added", function(snapshot) {
console.log(snapshot.key());
});
You can explore more on the Firebase 3 documentation site here.
What Ryan did was right. However, you have to implement startAt on the dataSnapshot to make sure that your "live" search works.