I just fetch data & load it into recyclerView that can be set on adapter. It contains a button which is able to send data to Firebase.
When I press the button its color and text changes as per requirement
but whenever I reload it again the default button state gets loaded.
So I want that button should save its state once clicked and whenever I reload the same activity it should be in the saved state.
viewHolder.send_req.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
final Integer taggedPosition = viewHolder.getAdapterPosition();
Log.d(TAG,"button click data:"+taggedPosition);
firebaseFirestore.collection("Users").document(u_id).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.getResult().exists()){
name = task.getResult().getString("name");
userID = task.getResult().getString("user_id");
firebaseFirestore.collection("Pets").whereEqualTo("name",name_data).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()){
for (final DocumentSnapshot documentSnapshot : task.getResult()){
docID = documentSnapshot.getId();
Log.d(TAG,"selected pet doc id:"+docID);
if (docID!= null){
final Map<String, Object> userMap = new HashMap<>();
final Map<String, Object> userMap1 = new HashMap<>();
userMap.put("doc_id",docID);
userMap.put("pet_id",pet_no);
userMap.put("sender_id",userID);
userMap.put("sender_name",name);
userMap.put("pet_name",name_data);
userMap.put("pet_profile",image_url);
userMap.put("timestamp",FieldValue.serverTimestamp());
//do not place request if data is already exist in document
firebaseFirestore.collection("Send_req").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
List<String> list = new ArrayList<>();
final Button send_req = (Button)v;
if (task.isSuccessful()){
for (DocumentSnapshot document : task.getResult()) {
list.add(document.getString("doc_id"));
list.add(document.getString("sender_id"));
}
if (!(list.contains(docID)&& list.contains(userID))){
send_req.setClickable(true);
Toast.makeText(context,"send request successfully",Toast.LENGTH_SHORT).show();
send_req.setText("Cancel Request");
send_req.setBackgroundColor(Color.RED);
String btnname =send_req.getText().toString();
String button_name = (String)userMap.put("btnName",btnname);
firebaseFirestore.collection("Send_req").add(userMap);
send_req.setClickable(false);
}
else {
if ((list.contains(docID)&& list.contains(userID))){
if(send_req.getText().toString().equals("Send Request") )
Toast.makeText(context,"you already send request",Toast.LENGTH_SHORT).show();
send_req.setText("Cancel Request");
send_req.setBackgroundColor(Color.RED);
send_req.setClickable(false);
notifyDataSetChanged();}
}
}
}
});
}
}
}
}
});
}
}
});
}
});
public class SomeClass {
public static boolean isFeatureSelected = false;
...
}
And you can always invoke it with SomeClass.isFeatureSelected.
If you already have the pojo of the response then you can define a variable in the pojo and change the value on button click on that position. As define by ChrisZ.
But if as you don't have pojo I will suggest you to create a List of Boolean size same as the recyclerView item size with false value. Once you click on the button make the list boolean to true at that position so you can know on which position you already clicked and change the UI with the bool value at that position.
Create a boolean variable such as:
boolean isClicked = false; and int pos = -1;
Then the first time you changed the button background change the boolean to true and pos = position;.
Then in the onBindViewHolder of your RecyclerView do this:
if(isClicked && position == pos){ // check the state of the button and the adapter position.
// change your background here
}
Related
I have String list as shown I want the selected item to be store in Firestore
Can you please tell me how it should be possible?
I have String list as shown I want the selected item to be store in Firestore
Can you please tell me how it should be possible?
public class Student_Register_Activity extends AppCompatActivity {
EditText etRegEmail,etname,etfathername,etRollno,etdepartment,etadress,etphonenmbr,semester,;
EditText etRegPassword;
String[] items={"Shinkiari","Mansehra","Abbottabad","Qalandarabad","Attersheesha","Khaki"};
AutoCompleteTextView autoCompleteText;
Button btnRegister;
ArrayAdapter<String> adapteritems;
FirebaseAuth mAuth;
FirebaseFirestore firestore=FirebaseFirestore.getInstance();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_student_register);
autoCompleteText=findViewById(R.id.auto_complete_txt);
adapteritems=new ArrayAdapter<String>(this,R.layout.list_item,items);
autoCompleteText.setAdapter(adapteritems);
autoCompleteText.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
String item =adapterView.getItemAtPosition(position).toString();
}
});
etRegEmail = findViewById(R.id.etRegEmail);
etRegPassword = findViewById(R.id.etRegPass);
btnRegister = findViewById(R.id.btnRegister);
etname = findViewById(R.id.etname);
etfathername = findViewById(R.id.etfname);
etRollno = findViewById(R.id.etRollno);
etdepartment = findViewById(R.id.etdepartment);
etadress = findViewById(R.id.etadress);
etphonenmbr = findViewById(R.id.etphonenmbr);
mAuth = FirebaseAuth.getInstance();
btnRegister.setOnClickListener(view -> createUser());
}
private void createUser(){
String email = etRegEmail.getText().toString();
String password = etRegPassword.getText().toString();
if (TextUtils.isEmpty(email)){
etRegEmail.setError("Email cannot be empty");
etRegEmail.requestFocus();
}else if (TextUtils.isEmpty(password)){
etRegPassword.setError("Password cannot be empty");
etRegPassword.requestFocus();
}else{
mAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
Toast.makeText(Student_Register_Activity.this, "Student registered successfully", Toast.LENGTH_SHORT).show();
FirebaseUser user = mAuth.getCurrentUser();
DocumentReference df = firestore.collection("Student").document(user.getUid());
//Map is used to store the data
Map<String,Object> userinfo = new HashMap<>();
userinfo.put("Name",etname.getText().toString());
userinfo.put("FName",etfathername.getText().toString());
userinfo.put("Email",etRegEmail.getText().toString());
userinfo.put("Password",etRegPassword.getText().toString());
userinfo.put("semester",etRegPassword.getText().toString());
userinfo.put("Transport", adapteritems.toString();
userinfo.put("Rollno",etRollno.getText().toString());
userinfo.put("Department",etdepartment.getText().toString());
userinfo.put("address",etadress.getText().toString());
userinfo.put("phone",etphonenmbr.getText().toString());
startActivity(new Intent(Student_Register_Activity.this, AdminDashboard.class));
//specify if user is student
userinfo.put("isStudent","1");
df.set(userinfo);
}else{
Toast.makeText(Student_Register_Activity.this, "Registration Error: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
}
I think you want to add selected items from list in user object, If that so you can follow below steps:
first declare global variable for selected
String selectedOption;
Then save value in on click of list
autoCompleteText.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
selectedOption =adapterView.getItemAtPosition(position).toString();
}
});
then use that value to save in user object
userinfo.put("city",selectedOption);
I have a activity where it displays candidate on recyclerview to cardview. All is functioning correctly except the code below greyed the button for only the first position. I will attach the screenshot below.
the output
it should be if only one field value is true on in all documents, all the button should be disabled. But as you can see, only the first button is disabled.
Here is my code:
db.collection("cancol").whereEqualTo(currentuser, true).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
Button btncan= findViewById(R.id.btncandidate);
Toast.makeText(NewVoteMainActivity.this, "You have already used your vote.", Toast.LENGTH_SHORT).show();
adapter.setOnItemClickListener(null);
int disabled = Color.parseColor("#c2c2c2");
btncan.setBackgroundColor(disabled);
}
});
I also tried this but also gives the same result:
db.collection("cancol").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
Toast.makeText(NewVoteMainActivity.this, "Retrieving Documents..." , Toast.LENGTH_SHORT).show();
List<String> list = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
if (document.getBoolean(currentuser) == true) {
Button btncan= findViewById(R.id.btncandidate);
Toast.makeText(NewVoteMainActivity.this, "You have already used your vote.", Toast.LENGTH_SHORT).show();
adapter.setOnItemClickListener(null);
int disabled = Color.parseColor("#c2c2c2");
btncan.setBackgroundColor(disabled);
}
}
How do I make the code apply to every button?
How do I write Shared-preference Code that is using Firebase for User authentication and the data that is saved by a user is only accessible for them?
My current application Saves a note and displays it which is the main thing needed in my project but when a user logs out and new user logs in he/she can also view the data so the data is not private. My sir suggested to make nodes for users using shared preference but i couldn't find any solutions
HomeActivity:
public class HomeActivity extends AppCompatActivity {
EditText Descriptionholder;
Button Savebtn;
DatabaseReference DatabaseNote;
ListView listViewNotes;
List<PrivateNote> privateNoteList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
DatabaseNote = FirebaseDatabase.getInstance().getReference("privatenote");
Descriptionholder = findViewById(R.id.description2);
Savebtn = findViewById(R.id.buttonsave);
listViewNotes= findViewById(R.id.listViewPrivate);
privateNoteList = new ArrayList<>();
Savebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addnote();
}
});
listViewNotes.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
PrivateNote privateNote = privateNoteList.get(i); //confusion
showUpdateDialog(privateNote.getNoteId(),privateNote.getNoteDescription());
return false;
}
});
}
public boolean onCreateOptionsMenu (Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.side, menu);
return true;
}
#Override
public boolean onOptionsItemSelected (MenuItem item){
switch (item.getItemId()) {
case R.id.item1:
FirebaseAuth.getInstance().signOut();
finish();
startActivity(new Intent(new Intent(this, MainActivity.class)));
Toast.makeText(this, "Logged out ", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onStart() {
super.onStart();
DatabaseNote.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
privateNoteList.clear();
for (DataSnapshot privateSnapshot: dataSnapshot.getChildren() ){
PrivateNote privateNote = privateSnapshot.getValue(PrivateNote.class);
privateNoteList.add(privateNote);
}
PrivateList adapter = new PrivateList(HomeActivity.this,privateNoteList);
listViewNotes.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void showUpdateDialog(final String noteId, String noteDescription){
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
final View dialogview = inflater.inflate(R.layout.update_dialouge,null);
dialogBuilder.setView(dialogview);
final EditText editDescription = dialogview.findViewById(R.id.editDescription);
final Button buttonUpdate = dialogview.findViewById(R.id.buttonUpdate);
final Button buttonDelete = dialogview.findViewById(R.id.buttonDelete);
dialogBuilder.setTitle("Updating Note: " +noteDescription);
final AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
buttonUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String description = editDescription.getText().toString().trim();
if (TextUtils.isEmpty(description)){
editDescription.setError(" New information required");
return;
}
updatePrivateNote(noteId,description);
alertDialog.dismiss();
}
});
buttonDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deletePrivateNote(noteId);
}
});
}
private void deletePrivateNote(String noteId) {
DatabaseReference drPrivateNote = FirebaseDatabase.getInstance().getReference("privatenote").child(noteId);
drPrivateNote.removeValue();
Toast.makeText(this, " Note Deleted", Toast.LENGTH_SHORT).show();
}
private boolean updatePrivateNote(String id,String description){
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("privatenote").child(id);
PrivateNote privateNote = new PrivateNote(id,description);
databaseReference.setValue(privateNote);
Toast.makeText(this, " Note Updated", Toast.LENGTH_SHORT).show();
return true;
}
private void addnote () {
String description = Descriptionholder.getText().toString().trim();
if (!TextUtils.isEmpty(description)){
//generated unique number for id
String id = DatabaseNote.push().getKey();
PrivateNote pNote = new PrivateNote(id, description);
DatabaseNote.child(id).setValue(pNote); //pNote value added in id
Toast.makeText(this, "Note added", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(this, " Please Enter a note ", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
FirebaseAuth.getInstance().signOut();
finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
Adapter:
public class PrivateList extends ArrayAdapter<PrivateNote> {
private Activity context;
private List<PrivateNote> privateNoteList;
public PrivateList(Activity context, List<PrivateNote> privateNoteList){
super(context, R.layout.list_layout,privateNoteList);
this.context =context;
this.privateNoteList=privateNoteList;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View listViewItem = inflater.inflate(R.layout.list_layout,null,true);
TextView textViewDescription = listViewItem.findViewById(R.id.TextViewDescription);
PrivateNote privateNote = privateNoteList.get(position);
textViewDescription.setText(privateNote.getNoteDescription());
return listViewItem;
}
}
PrivateNote:
public class PrivateNote {
public String noteId;
public String noteDescription;
public PrivateNote(){
}
PrivateNote(String noteId, String noteDescription){
this.noteId = noteId;
this.noteDescription=noteDescription;
}
String getNoteId()
{
return noteId;
}
String getNoteDescription()
{
return noteDescription;
}
}
In Firebase, there are two things,
FirebaseDatabase
FirebaseAuth
Usually, in almost all the apps, user data is stored in the FirebaseDatabase under the key, that is generated while creating a new user in your Firebase app.
So, for example, your database structure will look like this.
-Your_main_database
|____UserId_Of_FirebaseUser
|____stuff_related_to_user
|____More stuff related to user
So, you create a new user in FirebaseAuth, you can find more about it below:
Firebase Custom Auth.
Then, after creating a new user, you create child nodes under your database with the key=userId of your current logged in user.
eg. In your addNote function, the id variable will be equal to
String id = FirebaseAuth.getInstance().getCurrentUser().getUid();
Currently, you're using Push keys which are generated based on Timestamp, which you won't be able to associate with user unless you add a key inside your note object which stored current username, and then find all the child nodes that contain that username, but in that case, your data won't be organized at all.
Then, after you create a node with userId under your main database, you can then push new notes created by your user inside the userId with the push() function. So your database structure will look like below.
___
|
|__users
|__uniqueUserId
| |__note1
| |__note2
|__uniqueUserId2
|__note1
|__note2
|__note3
Next time whenever you want to fetch user created notes, you log in the user, get his ID, and then find the notes corresponding to that ID.
I don't see how you can fit SharedPreferences in there, before there is also function to cache data offline in Firebase once it is loaded.
Securing the notes:
If you implement the database like I said above, you'll be very easily able to secure your database.
Common Database Rules.
If you implement everything correctly like I told, you'll be able to secure your database with the fourth set of rules from above rules.
Since you are using firebase authentication, then you can retrieve the userId, and create the following database:
notes
userId
note : "todo"
description : "study"
Then you can do:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("notes");
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String userId = user.getUid();
ref.orderByKey().equalTo(userId).addValueEventListener(new ValueEventListener() {...}
This way you would retrieve the data of the currently logged in user only.
This question already has an answer here:
How to display data from Firestore in a RecyclerView with Android?
(1 answer)
Closed 4 years ago.
I am currently developing a mobile app in Android Studio. I have a collection in Firebase firestore called Leagues. When I open a fragment from the navigation drawer, the recyclerview is empty. I have two buttons at the top of the layout, both of which open an alert dialog. When I click on either of the buttons and click on the box to start entering text, the leagues magically appear in the recyclerview! Ideally I would like them to appear when the fragment is first opened. To give a bit more context I have a method which fetches the leagues from the collection in Firebase, but having debugged it I've found that this initially returns an empty list. Only when the edittext box in the alert dialog is pressed does the list fill up. Can anyone think why this might be the case?
Thanks in advance
Edit:
public class LeaguesFragment extends Fragment {
Button buttonCreateLeague;
Button buttonJoinLeague;
View view;
FirebaseFirestore firestore;
private String leagueID;
private String userID;
private String leagueName;
private String username;
TextView textViewMyLeagues;
RecyclerView recyclerView;
private List<Leagues> leaguesList;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_leagues, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.leaguesList);
RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(getContext(), leaguesList);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(recyclerViewAdapter);
buttonCreateLeague = (Button) view.findViewById(R.id.buttonCreateLeague);
buttonJoinLeague = (Button) view.findViewById(R.id.buttonJoinLeague);
textViewMyLeagues = (TextView) view.findViewById(R.id.textViewMyLeagues);
firestore = FirebaseFirestore.getInstance();
userID = FirebaseAuth.getInstance().getUid();
firestore.collection("users").document(userID).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()) {
DocumentSnapshot documentSnapshot = task.getResult();
username = documentSnapshot.getString("name");
}
}
});
buttonCreateLeague.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
leagueID = CreateLeagueID.randomString(6);
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage("Enter league name");
final EditText input = new EditText(getContext());
alert.setView(input);
alert.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
leagueName = input.getText().toString().trim();
createLeague(leagueID, leagueName);
addUserToLeague(leagueID, username);
addLeagueToUser(leagueID, userID, leagueName);
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Cancelled.
}
});
alert.show();
}
});
buttonJoinLeague.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage("Enter league code");
final EditText input = new EditText(getContext());
alert.setView(input);
alert.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
leagueID = input.getText().toString().trim();
firestore.collection("leagues").document(leagueID).collection("members").document(username).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()) {
DocumentSnapshot documentSnapshot = task.getResult();
if(documentSnapshot.exists()) {
Toast.makeText(getActivity(), "Already part of this league", Toast.LENGTH_SHORT).show();
}
else {
firestore.collection("leagues").document(leagueID).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot documentSnapshot = task.getResult();
if (documentSnapshot.exists()) {
leagueName = documentSnapshot.getString("leagueName");
addUserToLeague(leagueID, username);
addLeagueToUser(leagueID, userID, leagueName);
}
else {
Toast.makeText(getActivity(), "That league does not exist", Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
}
});
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Cancelled.
}
});
alert.show();
}
});
return view;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
leaguesList = new ArrayList<>();
firestore = FirebaseFirestore.getInstance();
userID = FirebaseAuth.getInstance().getUid();
firestore.collection("users").document(userID).collection("leagues").addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, #javax.annotation.Nullable FirebaseFirestoreException e) {
if(e != null) {
Log.d(TAG, "Error : " + e.getMessage());
}
for(DocumentChange doc: queryDocumentSnapshots.getDocumentChanges()) {
if(doc.getType() == DocumentChange.Type.ADDED) {
//leagueID = doc.getDocument().getString("leagueID");
//leagueName = doc.getDocument().getString("leagueName");
Leagues leagues = doc.getDocument().toObject(Leagues.class);
leaguesList.add(leagues);
}
}
}
});
}
having debugged it I've found that this initially returns an empty list.
Yes, this the normal behaviour. You cannot use now something that hasn't been loaded yet. With other words, you cannot simply create the leaguesList variable as global variable and use it outside the onEvent() method because it will always be empty due the asynchronous behaviour of this method. This means that by the time you are trying to use that list outside that method, the data hasn't finished loading yet from the database and that's why is not accessible. A quick solve for this problem would be to use leaguesList list only inside the onEvent() method, otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.
Maybe the problem is your leaguesList still empty when onCreateView is trigger. And when onEvent from firestore trigger you not notify data set change the adapter.
I am developing an Android app, and I have already implemented authentication with Firebase. After logging in, in my NavigationDrawerActivity I have a ListView that I had set a FirebaseListAdapater to that gets user specific data.
In my onCreate() method I have the following:
firebaseAuth = FirebaseAuth.getInstance();
FirebaseUser localUser = firebaseAuth.getCurrentUser();
String localUserEmail = localUser.getEmail();
String localUserEmailUniqueID = getEmailAddressUniqueID(localUserEmail);
String dbUsersRoot = "https://DATABASENAME.firebaseio.com/Users/";
String dbUniqueRefForCurrentUser = dbUsersRoot + localUserEmailUniqueID +"/parishioners";
DatabaseReference databaseReferenceCurrentUser = FirebaseDatabase.getInstance().getReferenceFromUrl(dbUniqueRefForCurrentUser);
final FirebaseListAdapter<String> firebaseListAdapter = new FirebaseListAdapter<String>(
this,
String.class,
android.R.layout.simple_list_item_2,
databaseReferenceCurrentUser
) {
#Override
protected void populateView(View v, String model, int position) {
TextView textView = (TextView) v.findViewById(android.R.id.text1);
textView.setText(model);
}
};
mListView.setAdapter(firebaseListAdapter);
Now, in my onStart() method I have added an setOnClickListener to a button that wishes to add a new item into my list , like this :
#Override
protected void onStart(){
super.onStart();
mButtonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
firebaseAuth = FirebaseAuth.getInstance();
FirebaseUser localUser = firebaseAuth.getCurrentUser();
String localUserEmail = localUser.getEmail();
String localUserEmailUniqueID = getEmailAddressUniqueID(localUserEmail);
String dbUsersRoot = "https://DATABASENAME.firebaseio.com/Users/";
String dbUniqueRefForCurrentUser = dbUsersRoot + localUserEmailUniqueID +"/parishioners";
DatabaseReference databaseReferenceCurrentUser = FirebaseDatabase.getInstance().getReferenceFromUrl(dbUniqueRefForCurrentUser);
databaseReferenceCurrentUser.push().setValue(editTextNewMember.getText().toString().trim());
}
});
}
On clicking the Add Button, I'll have in my database something like this (supposing the EditText has in it the string 'capuccino'):
"luminittta" : {
"parishioners" : {
"-KX1GcEWPMy7oFWgt_3h" : "capuccino"
Now, my List will show 'capuccino' (since it's a realtime database my list will automatically get updated with the newly added value).
My question is:
How can I implement next a delete functionality that when the user long clicks an item from the ListView it gets removed?
Entire Database looks like this:
{
"Users" : {
"davidivanmircea" : {
"parishioners" : {
"-KX1FNcgSXgsMNz6QRIS" : "Gus Crick",
"-KX1FVIzzPM4nMrMvm9x" : "Florentino Williams",
"-KX1FZ27M-KS5TQZQ76u" : "Marc Raff",
"-KX1FbercKpPrl9r9tb4" : "Frederick Haddon",
"-KX1FgguOlRRN4sZKS8Z" : "Cristobal Wolfe",
"-KX1FkgwifQLIHplsZNx" : "Scott Nodal",
"-KX1Fp64Sa2QD94GR9uK" : "Odis Nevers",
"-KX1FrYK5PeuBucEiamY" : "Chauncey Mossman",
"-KX1FvIBDSrvppC3e4Ip" : "Alfonso Ignacio",
"-KX1Fy7dEHH8Z9JV-BRL" : "Douglas Hettinger",
"-KX1WdtbV4PEiscJV6E_" : "Daniel Muresan",
"-KX1WvYqekJZdWS6wGh6" : "Angelina Jolie"
}
},
"luminittta" : {
"parishioners" : {
"-KX1GYuSsgmHyGk5LQLA" : "mocha",
"-KX1G_Q130sWitNGzlAR" : "triplo",
"-KX1GaPIhuIyhV4vmLGe" : "latte",
"-KX1GcEWPMy7oFWgt_3h" : "capuccino",
"-KX1Gf7TKY3N8IQETig-" : "machiatto",
"-KX1Gh4KoYpcVpCDFI2x" : "cafe melange",
"-KX1GoCutX3XO-CRWWB3" : "ristretto",
"-KX1GpvdE5i9UR2ZaX0K" : "americano",
"-KX1Grb8S5QZu4HT9cuW" : "espresso"
}
}
}
}
Thank you very much for your help !
PS: I have modified my actual database name with 'DATABASENAME' inside the code.
Change your "populateView" to this one:
#Override
protected void populateView(View v, String model, int position) {
TextView textView = (TextView) v.findViewById(android.R.id.text1);
textView.setText(model);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mRecycleViewAdapter.getRef(position).removeValue();
Log.d("TAG", model + " removed from the list");
}
});
}
};
To remove a specific item on LongClick write this in populateView
v.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
getRef(position).removeValue();
notifyDataSetChanged();
return true;
}
});
After reading the code Nirel and Frank provided, I changed my FirebaseListAdapter into a RecyclerView succesfully and implemented my Delete functionality (on clicking the item from the list).
For the record, RecyclerView does not come with an onClickListener by itself, so anyone who will be in the same situation as I was will need to implement it. I have used http://www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/ and it works like a charm.