In my ExploreFragment.java I have an EditText which basically allows the user to search country names that are stored in my Firebase Realtime Database.
What I want to achieve is, when the user types something in the EditText and then presses "submit" in their keyboard, it makes a query that retrieves every country which has the string they typed in their name, and get redirected to my fragment FilteredResultsFragment.java which displays the names of the countries retrieved. My fragment has a recycler view with an Adapter.
I haven't achieved this yet. I need to retrieve a List with the urls and a List with the names.
The query should look like this:
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
Log.d("TAMANHO","size = "+paisEscolhido.size());
for (int i = 0; i<paisEscolhido.size(); i++) {
Log.d("CONTINETNE","size = "+paisEscolhido.get(i));
DatabaseReference paisNomeContinentes = mDatabase.getReference().child("paises");
Query queries = paisNomeContinentes.orderByChild("Continente").equalTo(paisEscolhido.get(i));
queries.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
List<String> imagemPaisList = new ArrayList<>();
List<String> nomePaisList = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String imagemPais = ds.child("Imagem").getValue(String.class);
String nomePais = ds.child("Nome").getValue(String.class);
imagemPaisList.add(imagemPais);
nomePaisList.add(nomePais);
}
int urlCount = imagemPaisList.size();
// int randomImage = new Random().nextInt(urlCount);
for (int i = 0; i < nomePaisList.size(); i++) {
Integer randomVariavel = new Random().nextInt(urlCount);
randomImagemPaisList.add(imagemPaisList.get(randomVariavel));
randomNomePaisList.add(nomePaisList.get(randomVariavel));
}
UPDATE
I've come up with this query:
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference paisNomeContinentes = mDatabase.getReference().child("paises");
Query queries = paisNomeContinentes.orderByChild("Nome").startAt("Po");
queries.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
List<String> imagemPaisList = new ArrayList<>();
List<String> nomePaisList = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String imagemPais = ds.child("Imagem").getValue(String.class);
String nomePais = ds.child("Nome").getValue(String.class);
imagemPaisList.add(imagemPais);
nomePaisList.add(nomePais);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
That should retrieve the Name of the country that starts with the value the user writes in my EditText but, when I write, for example "Po", it should give me "Portugal" and "Poland" but, instead, it gives me random images...
This is the data structure:
UPDATE V2
It actually gives me "Poland" and "Portugal" as the top results but it shows my more ImageView besides those two (and with random images too)...
If you want to use startAt() to filter your data you also have to use endAt() because startAt() works as a starting point for your query and not a filter. By adding \uf8ff (the last unicode character) behind your searchstring in endAt() you limit your query to get only the values that start with your searchstring:
Query queries = paisNomeContinentes.orderByChild("Nome").startAt("Po").endAt("Po" + "\uf8ff");
Just remember this will only get the items that start with the searchstring, not the items that contain the searchstring.
Related
I want to get data from firebase in sorted manner, I tried below method but its not working propely and collects all the data.
Here is the image for my firebase database :
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference();
String input = "G";
Date cd = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy", Locale.getDefault());
String formattedDate = df.format(cd);
FirebaseUser currentUser = mAuth.getCurrentUser();
DatabaseReference data = databaseRef.child("Data").child(currentUser.getUid()).child(formattedDate.toString()).child(medname.toString());
databaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
List<String> data = new ArrayList<String>();
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
data.add(postSnapshot.getValue().toString());
}
Log.d("datafriebase",""+data);
}
I want to get data in sorted manner, like value of 1, value of 2 but i am getting whole database
You're getting the whole database, because you're reading from databaseRef, which you initialized as:
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference();
To get only the nested data, read from data, which you set to reference that path:
DatabaseReference data = databaseRef.child("Data").child(currentUser.getUid()).child(formattedDate.toString()).child(medname.toString());
So:
data.addValueEventListener(new ValueEventListener() {
...
I'm developing an app:
In my realtime database I have this structure
But some keys have the same data and it's a duplicate like this:
In my Android Studio project I code this function but only retrieve the data but no check the duplicates:
private void deleteIfAreDuplicateData() {
List<Order> orderList = new ArrayList<>();
FirebaseDatabase.getInstance().getReference(Common.ORDER_REF)
.orderByKey()
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
ArrayList<Object> numeroDeOrden = new ArrayList<>();
String datos;
String pagoFinal, tiempo, idUsuario, nombreUsuario;
boolean exists = false;
for (DataSnapshot orderSnapshot : dataSnapshot.getChildren()) {
Map<String, Object> model = (Map<String, Object>) orderSnapshot.getValue();
pagoFinal = String.valueOf(orderSnapshot.child("finalPayment").getValue());
tiempo = String.valueOf(orderSnapshot.child("orderTime").getValue());
idUsuario = String.valueOf(orderSnapshot.child("userId").getValue());
nombreUsuario = String.valueOf(orderSnapshot.child("userName").getValue());
datos = (String) orderSnapshot.getKey();
numeroDeOrden.add(datos);
for (int i = 0; i < numeroDeOrden.size(); i++) {
if (model.get("finalPayment").equals(pagoFinal) && model.get("orderTime").equals(tiempo)) {
exists = true;
}
}
}
if(exists)
{
Toast.makeText(getContext(), "Tienes ordenes repetidas ", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
How can I check for duplicate in the database and when I have the duplicates remove only one of the 2 values (?)
If you want to prevent duplicate values, use those values as the keys for the data. So in your case, if you want the combination of all property values to be unique, combine all of those values into a single string and use that as your key.
You'll want to remove or encode any characters that are not allowed in keys, so ., $, [, ], #, and /, from the key.
In addition, if the key becomes longer than the maximum key length of 768 characters, you'll want to reduce it down to size too with a hash function or by simply truncating the string. See my answer here for some more info on that: Firebase Error: First argument has a key path longer than 768 Bytes
You can have a list of your model saved in your activity (or typically in ViewModel as a static member):
pubic static List<Map<String, Object>> modelList;
Then for each change in data you can add only the new data to the model by checking if exists using contains() method:
for (DataSnapshot orderSnapshot : dataSnapshot.getChildren()) {
Map<String, Object> model = (Map<String, Object>) orderSnapshot.getValue();
if (!modelList.contains(model)) {
modelList.add(model);
// Add your rest of code for the incoming new/change of data
}
}
I have a method that I cdreated called getAssignedCustomerLocation that creates a database reference with the variable name assignedCustomerRef but,that database reference does not actually show up in my firebase console. No node is created on the actual console for it. Code below
public void getAssignedCustomerLocation(){
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference assignedCustomerRef = FirebaseDatabase.getInstance().getReference().child("customerRequest").child(userId).child("l");
assignedCustomerRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
List<Object> map = (List<Object>) dataSnapshot.getValue();
double locationLat = 0;
double locationLong =0;
if (map.get(0)!=null) {
locationLat= Double.parseDouble(map.get(0).toString());
}
if (map.get(1)!=null){
locationLong = Double.parseDouble(map.get(1).toString());
}
LatLng driverLatLong = new LatLng(locationLat,locationLong);
mMap.addMarker(new MarkerOptions().position(driverLatLong).title("your driver"));
}
}
The code you have used is to read from firebase. If you want to write a new node to the db use below.
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference assignedCustomerRef = FirebaseDatabase.getInstance().getReference().child("customerRequest").child(userId).child("l");
assignedCustomerRef.setValue("YOUR_DATA");
To create a node in the database you need to use setValue(), so you can do the following:
DatabaseReference assignedCustomerRef = FirebaseDatabase.getInstance().getReference().child("customerRequest").child(userId);
assignedCustomerRef.child("l").setValue("your driver");
I have a code (which works) that makes me able to retrieve all the countries of a specific continent:
DatabaseReference paisNomeContinentes = mDatabase.child("continentes").child(Constants.PAISES_EUROPA).child("Paises"); // C1 - ÁFRIA (Constants.PAISES_AFRICA)
ValueEventListener valueEventListener1 = new ValueEventListener() { // C2 - ÁSIA (Constants.PAISES_ASIA)
#Override // C3 - ANTÁRTIDA (Constants.PAISES_ANTARTIDA)
public void onDataChange(DataSnapshot dataSnapshot) { // C4 - AMÉRICA (Constants.PAISES_AMERICA)
List<String> nomePaisList = new ArrayList<>(); // C5 - EUROPA (Constants.PAISES_EUROPA)
// C6 - OCEANIA (Constants.PAISES_OCEANIA)
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String nomePais = ds.child("Nome").getValue(String.class);
nomePaisList.add(nomePais);
}
int urlCount = nomePaisList.size();
int randomNumber = new Random().nextInt(urlCount);
List<String> randomNomePaisList = new ArrayList<>();
for (int i=0; i<=9; i++) {
randomNomePaisList.add(nomePaisList.get(randomNumber));
txtHomeDesc.setText(randomNomePaisList.get(i)); // Inserir na TextView o nome do respetivo país
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
paisNomeContinentes.addListenerForSingleValueEvent(valueEventListener1);
And this is the structure of my Firebase Realtime Database for this code:
I created this structure for testing. I ended up using this instead:
The problem is, the code I have doesn't work for this structure. How can I retrieve the countries which have the Continente = Europa?
You need to use a query:
FirebaseDatabase mDatabase=FirebaseDatabase.getInstance();
DatabaseReference paisNomeContinentes = mDatabase.getReference().child("paises");
Query queries=paisNomContinentes.orderByChild("Continente").equalTo("Europa");
queries.addListenerForSingleValueEvent(valueEventListener1);
The snapshot is at child paises then using the query you will be able to retrieve the data that has Continente=Europa
so i am stuck. i want to retrieve child of child from my firebase database.
my database struture looks like this
users{
user1{
name:
regno:
carmodel:
caryear}
user2{
name:
regno:
carmodel:
caryear}
user3{
name:
regno:
carmodel:
caryear}}
Regno = car registration number.
when i type in a "carreg no" and press ok. i want the code to search every carreg. if a match is found execute next set of codes.
so far i have tried to store it in a array. but the code seems to fail when i put reg or any variable name that exist.
public void input(){
FirebaseDatabase firebase = FirebaseDatabase.getInstance();
final DatabaseReference table_user = firebase.getReference("User");
table_user.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Get map of users in datasnapshot
collectPhoneNumbers((Map<String,Object>) dataSnapshot.getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
private void collectPhoneNumbers(Map<String,Object> users) {
ArrayList<Long> phoneNumbers = new ArrayList<>();
//iterate through each user, ignoring their UID
for (Map.Entry<String, Object> entry : users.entrySet()){
//Get user map
Map singleUser = (Map) entry.getValue();
//Get phone field and append to list
phoneNumbers.add((Long) singleUser.get("namesd"));
}
System.out.println(phoneNumbers.toString());
mVoiceInputTv.setText("" + phoneNumbers);
}
}
i got this from another stackflow. before this i tried creating a for look. it was successfull but result failed 80% of the time. (not always correct).
To solve this, you need to query your database using orderByChild() method like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
Query regnoQuery = usersRef.orderByChild("regno").equalsTo(regno);
In which regno argument from equalsTo() is the the actual registration number that you are looking for. Then attach a listener to the regnoQuery and use getChildrenCount() method on the dataSnapshot object. If the number of childrens is noOfChildrens > 0 then execute the set of codes you need.
private FirebaseDatabase mdatabase;
private DatabaseReference mdatabaseRef;
mdatabase = FirebaseDatabase.getInstance();
mdatabaseRef = mdatabase.getReference();
mdatabaseRef.child("users").child("users1").orderByChild("regno").equalsTo(regno).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
}
}