0

In my app my user is entering the category and that category is stored in the FirebseDB. After storing the value in the DB the user can view the inserted value in the Spinner.

At this point all works fine.

I want user to enter only unique value .so , if user wants to enter the value which is already there he should get a Toast.

Following is my activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.lenovo.baicactivitytest.MainActivity">

    <Spinner
    android:id="@+id/sp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

    <Button
        android:id="@+id/add_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="70dp"
        android:text="Add" />

</RelativeLayout>

Following is my inputdialogue.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="?attr/actionBarSize"
        android:orientation="vertical"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingTop="50dp">
        <android.support.design.widget.TextInputLayout
            android:id="@+id/nameLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:id="@+id/nameEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:singleLine="true"
                android:hint= "Name" />
        </android.support.design.widget.TextInputLayout>
        <Button android:id="@+id/saveBtn"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Save"
            android:clickable="true"
            android:background="@color/colorAccent"
            android:layout_marginTop="40dp"
            android:textColor="@android:color/white"/>
    </LinearLayout>
</LinearLayout>

Spacecraft.java

package com.example.lenovo.baicactivitytest;

/**
 * Created by LENOVO on 29-12-2017.
 */

public class Spacecraft {
    String name;
    public Spacecraft() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

FirebaseHelper

package com.example.lenovo.baicactivitytest;

import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.DatabaseReference;

import java.util.ArrayList;

/**
 * Created by LENOVO on 29-12-2017.
 */

public class FirebaseHelper {
    DatabaseReference db;
    Boolean saved = null;
    public FirebaseHelper(DatabaseReference db) {
        this.db = db;
    }
    //SAVE
    public  Boolean save(Spacecraft spacecraft)
    {
        if(spacecraft==null)
        {
            saved=false;
        }else
        {
            try
            {
                db.child("Spacecraft").push().setValue(spacecraft);
                saved=true;
            }catch (DatabaseException e)
            {
                e.printStackTrace();
                saved=false;
            }
        }
        return saved;
    }
    //READ
    public ArrayList<String> retrieve()
    {
        final ArrayList<String> spacecrafts=new ArrayList<>();
        db.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                fetchData(dataSnapshot,spacecrafts);
            }
            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                fetchData(dataSnapshot,spacecrafts);
            }
            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
            }
            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });
        return spacecrafts;
    }
    private void fetchData(DataSnapshot snapshot,ArrayList<String> spacecrafts)
    {
        spacecrafts.clear();
        for (DataSnapshot ds:snapshot.getChildren())
        {
            String name=ds.getValue(Spacecraft.class).getName();
            spacecrafts.add(name);
        }
    }
}

MainActivity.java

package com.example.lenovo.baicactivitytest;

import android.app.Dialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

public class MainActivity extends AppCompatActivity {
    DatabaseReference db;
    FirebaseHelper helper;
    private Button madd_btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Spinner sp =(Spinner) findViewById(R.id.sp);
        //SETUP FB
        db= FirebaseDatabase.getInstance().getReference();
        helper = new FirebaseHelper(db);
        ArrayAdapter<String>  adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,helper.retrieve());
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        sp.setAdapter(adapter);
        madd_btn = (Button) findViewById(R.id.add_btn);
        madd_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                displayInputDialog();
            }
        });
    }
    //DISPLAY INPUT DILAOG
    private void displayInputDialog()
    {
        Dialog d=new Dialog(this);
        d.setTitle("Firebase database");
        d.setContentView(R.layout.inputdialog);
        final EditText nameTxt= (EditText) d.findViewById(R.id.nameEditText);
        Button saveBtn = (Button) d.findViewById(R.id.saveBtn);
        //SAVE
        saveBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //GET DATA
                String name=nameTxt.getText().toString();
                //set data
                Spacecraft s = new Spacecraft();
                s.setName(name);
                //SAVE
                if(name != null && name.length()>0)
                {
                    if(helper.save(s))
                    {
                        nameTxt.setText("");
                    }
                }else
                {
                    Toast.makeText(MainActivity.this, "Name Cannot Be Empty", Toast.LENGTH_SHORT).show();
                }
            }
        });
        d.show();
    }
}
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
  • The typical solution in Firebase is to use the value you want to be unique as the key in the database (so instead of calling `push()` you'd call `child(thingThatMustBeUnique)`). Then using security rules you'd prevent overwriting of existing data with `".write": "!data.exists()"`, and finally check in the client whether the item already exists with a listener. For more on this approach see https://stackoverflow.com/q/35243492, https://stackoverflow.com/q/25294478,https://stackoverflow.com/q/39149216. – Frank van Puffelen Dec 30 '17 at 16:10
  • Hi thanks for the suggestion but the link you have provided is not working –  Jan 08 '18 at 11:18
  • The solution described in each of those links is the idiomatic/proven way to ensure that the value of a certain property is unique within the Firebase Database. If you're having trouble implementing it, show what you've tried. – Frank van Puffelen Jan 08 '18 at 15:55

1 Answers1

1

Can do this:

 DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("Category");
ref.orderByChild("categoryname").equalTo(name).addValueEventListener(new ValueEventListener(){
 @Override
public void onDataChange(DataSnapshot dataSnapshot){
  if(dataSnapshot.exist()) {
      Toast.makeText(MainActivity.this, "Name already exists", Toast.LENGTH_SHORT).show();

      }
    }

Can do the above, it will search in the Category node in the db, and if it exists then it will give you the Toast message.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
  • @AakashBidlan you need to add the above in the place where you are storing the values in the database.. So it checks before storing it, so lets say you have a button that on clicking it then it will store values to the db, you add the code above so it checks before storing – Peter Haddad Dec 30 '17 at 08:56
  • i am adding it in the FirebaseHelper class. so in the Toast instead of MainActivity.this what should i put to pop-up the toast –  Dec 30 '17 at 09:07
  • @AakashBidlan put `getApplicationContext()` instead of mainactivity.this – Peter Haddad Dec 30 '17 at 09:09
  • It is showing cannot resolved method getApplicationContext() –  Dec 30 '17 at 09:13
  • @AakashBidlan do this in your class `private static Context context; public FirebaseHelper(Context c) { context = c; }` and then inside Toast add `context` instead of `mainactivity.this` – Peter Haddad Dec 30 '17 at 09:15
  • i added all the code and application is also running but it is unable to restrict the duplicate value. –  Dec 30 '17 at 09:29
  • @AakashBidlan add `return;` after the Toast – Peter Haddad Dec 30 '17 at 09:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/162212/discussion-between-aakashbidlan-and-peter-haddad). –  Dec 30 '17 at 09:43
  • return true OR return false ? –  Dec 30 '17 at 09:51
  • `Toast.makeText(context, "Name already exists", Toast.LENGTH_SHORT).show(); return;` @AakashBidlan – Peter Haddad Dec 30 '17 at 09:55
  • @AakashBidlan what didn't work, this is usually the way that is used in firebase to check if exists or not this should check if the child exists then it will exit the method – Peter Haddad Jan 08 '18 at 18:40