I am struggling to make a tie between my users in Firebase, and data that I want it to be linked to.
At the moment I am able to create users and log in with users credentials. Additionally, I am able to create Maintenance Issues using my MaintenanceActivity.
However, when I log in with an arbitrary user, the same maintenance issues will always show.
I am unsure how to link the User ID of each user to a maintenance issue, so that when a user logs in only their maintenance issues will show.
Totally unsure on where to start here, so any help would be much appreciated. Been struggling with this for a few days.
SignUpActivity
This creates users in the 'Users' table in my Firebase database, but I also want it to contain the User ID which can be linked to maintenance issues.
mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
final DatabaseReference[] ref = new DatabaseReference[1];
final FirebaseUser[] mCurrentUser = new FirebaseUser[1];
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Toasty.info(getApplicationContext(), "creation of account was: " + task.isSuccessful(), Toast.LENGTH_SHORT).show();
if (task.isSuccessful()) {
mCurrentUser[0] = task.getResult().getUser();
ref[0] =mDatabase.child(mCurrentUser[0].getUid());
ref[0].child("email").setValue(email);
Intent intent = new Intent(SignUpActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
}
});
MaintenanceActvity
public class MaintenanceActivity extends AppCompatActivity {
EditText editTextTitle;
EditText editTextDesc;
Spinner spinnerPrimary;
Spinner spinnerSecondary;
Spinner spinnerProperty;
Button buttonSubmit;
DatabaseReference databaseMaintenance;
ListView listViewIssues;
List<Maintenance> maintenanceList;
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference fDatabaseRoot = database.getReference();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maintenance);
Toolbar toolbar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
ab.setDisplayHomeAsUpEnabled(true);
databaseMaintenance = FirebaseDatabase.getInstance().getReference("maintenance");
editTextTitle = (EditText) findViewById(R.id.editTextTitle);
editTextDesc = (EditText) findViewById(R.id.editTextDesc);
buttonSubmit = (Button) findViewById(R.id.buttonSubmit);
spinnerPrimary = (Spinner) findViewById(R.id.spinnerPrimary);
spinnerSecondary = (Spinner) findViewById(R.id.spinnerSecondary);
spinnerProperty = (Spinner) findViewById(R.id.spinnerProperty);
listViewIssues = (ListView) findViewById(R.id.listViewIssues);
maintenanceList = new ArrayList<>();
buttonSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addMaintenance();
}
});
listViewIssues.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Maintenance maintenance = maintenanceList.get(position);
showMoreInfoDialog(maintenance.getMaintenanceId(), maintenance.getMaintenanceTitle(), maintenance.getMaintenanceDescription(), maintenance.getMaintenancePrimary(), maintenance.getMaintenanceSecondary(), maintenance.getMaintenanceProperty());
return false;
}
});
}
#Override
protected void onStart() {
super.onStart();
databaseMaintenance.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
maintenanceList.clear();
for(DataSnapshot maintenanceSnapshot : dataSnapshot.getChildren()){
Maintenance maintenance = maintenanceSnapshot.getValue(Maintenance.class);
maintenanceList.add(maintenance);
}
MaintenanceList adapter = new MaintenanceList (MaintenanceActivity.this, maintenanceList);
listViewIssues.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
fDatabaseRoot.child("properties").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Is better to use a List, because you don't know the size
// of the iterator returned by dataSnapshot.getChildren() to
// initialize the array
final List<String> propertyAddressList = new ArrayList<String>();
for (DataSnapshot addressSnapshot: dataSnapshot.getChildren()) {
String propertyAddress = addressSnapshot.child("propertyAddress").getValue(String.class);
if (propertyAddress!=null){
propertyAddressList.add(propertyAddress);
}
}
Spinner spinnerProperty = (Spinner) findViewById(R.id.spinnerProperty);
ArrayAdapter<String> addressAdapter = new ArrayAdapter<String>(MaintenanceActivity.this, android.R.layout.simple_spinner_item, propertyAddressList);
addressAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProperty.setAdapter(addressAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void showMoreInfoDialog(final String id, String maintenanceTitle, String maintenanceDescription, String maintenancePrimary, String maintenanceSecondary, String maintenanceProperty) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.more_info_dialog, null);
dialogBuilder.setView(dialogView);
final EditText editTextTitle = (EditText) dialogView.findViewById(R.id.editTextTitle);
final EditText editTextDesc = (EditText) dialogView.findViewById(R.id.editTextDesc);
final Button buttonUpdate = (Button) dialogView.findViewById(R.id.buttonUpdate);
final Spinner spinnerPrimary = (Spinner) dialogView.findViewById(R.id.spinnerPrimary);
final Spinner spinnerSecondary = (Spinner) dialogView.findViewById(R.id.spinnerSecondary);
final Spinner spinnerProperty = (Spinner) dialogView.findViewById(R.id.spinnerProperty);
final Button buttonDelete = (Button) dialogView.findViewById(R.id.buttonDelete);
dialogBuilder.setTitle("Updating Maintenance " + maintenanceTitle);
final AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
buttonUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String title = editTextTitle.getText().toString().trim();
String desc = editTextDesc.getText().toString().trim();
String primary = spinnerPrimary.getSelectedItem().toString();
String secondary = spinnerSecondary.getSelectedItem().toString();
String property = spinnerProperty.getSelectedItem().toString();
if(TextUtils.isEmpty(title)){
editTextTitle.setError("Title Required");
return;
}
updateMaintenance(title, desc, id, primary, secondary, property);
alertDialog.dismiss();
}
});
private boolean updateMaintenance(String title, String desc, String id, String primary, String secondary, String property) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("maintenance").child(id);
Maintenance maintenance = new Maintenance (id, title, desc, primary, secondary, property);
databaseReference.setValue(maintenance);
Toast.makeText(this, "Maintenance Updated Updated Successfully", Toast.LENGTH_LONG).show();
return true;
}
private void addMaintenance(){
String title = editTextTitle.getText().toString().trim();
String desc = editTextDesc.getText().toString().trim();
String primary = spinnerPrimary.getSelectedItem().toString();
String secondary = spinnerSecondary.getSelectedItem().toString();
String property = spinnerProperty.getSelectedItem().toString();
if(!TextUtils.isEmpty(title)){
String id = databaseMaintenance.push().getKey();
Maintenance maintenance = new Maintenance (id, title, desc, primary, secondary, property);
databaseMaintenance.child(id).setValue(maintenance);
Toast.makeText(this, "Maintenance Added", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "You must enter a maintenance record", Toast.LENGTH_LONG).show();
}
}
}
Firebase Database
Database Rules are as follows:
{
"rules": {
"users": {
"$uid": {
".write": "$uid === auth.uid",
".read": "$uid === auth.uid"
}
}
}
}
A basic approach that u can take is have a User Id for every maintenance node that you push.
So as per your firebase database you have a user ID "bfPG...."
This id can be the parent node for every maintenance record.
If you change this line to this
String id = databaseMaintenance.push().getKey();
this
String id = FirebaseAuth.getInstance().getCurrentUser().getUID(); //Check Syntax
you'll be pushing a maintenance record under a user ID and you can then differentiate maintenance records with different users.
Thus in order to get the records for a specific user you have to change your firebase query.
databaseMaintenance = FirebaseDatabase.getInstance().getReference("maintenance").orderByKey().equalTo(id);
https://firebase.google.com/docs/database/android/lists-of-data
check the link about how to filter records.
Another approach is you have an adapter to which you are adding maintenance records so before you add a record you can check if it belongs to the current user or not and add records accordingly.
Related
I wanted to ask for your help with something that eating my brain out since I am new at Firebase and android studio. I created this attendance app but only the admin can log into the system then as the admin he has the ability to add students and teachers so that they can have access to the system when they want to log in the system. but once I add a teacher he cannot log in the system. the system saying incorrect username and password while the credentials are all well-typed. is there a way to give access to a user without creating the sign-up page. I am using firebase as the database. here is my code for adding a teacher
public class FacultyAddActivity extends AppCompatActivity {
private Toolbar addFacTool;
private EditText facName, facEmail, facPhone, facID, facAddress;
private Spinner facSpinner;
private String[] designList;
private String selectDesign;
private Button addFacBtn;
private String intentMode, intentFac;
private DatabaseReference facReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_faculty_add);
addFacTool = findViewById(R.id.toolAdd);
setSupportActionBar(addFacTool);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
Intent intent = getIntent();
intentFac = intent.getStringExtra("FACULTY");
intentMode = intent.getStringExtra("MODE");
facName = findViewById(R.id.txtLName);
facEmail = findViewById(R.id.txtLEmail);
facAddress = findViewById(R.id.txtLAddress);
facPhone = findViewById(R.id.txtLPhone);
facID = findViewById(R.id.txtLID);
addFacBtn = findViewById(R.id.btnLSubmit);
facSpinner = findViewById(R.id.spnDes);
designList = getResources().getStringArray(R.array.designation);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(FacultyAddActivity.this, android.R.layout.simple_list_item_1, designList);
facSpinner.setAdapter(arrayAdapter);
facSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
selectDesign = parent.getItemAtPosition(position).toString();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
addFacBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addFaculty();
}
});
}
private void addFaculty() {
String name = facName.getText().toString();
String email = facEmail.getText().toString();
String address = facAddress.getText().toString();
String phone = facPhone.getText().toString();
String ID = facID.getText().toString();
if (name.isEmpty()){
facName.setError("Enter lecturer name");
facName.requestFocus();
}
else if (email.isEmpty()){
facEmail.setError("Enter lecturer email");
facEmail.requestFocus();
}
else if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()){
facEmail.setError("Enter lecturer email");
facEmail.requestFocus();
}
else if (address.isEmpty()){
facAddress.setError("Enter lecturer address");
facAddress.requestFocus();
}
else if (phone.isEmpty()){
facPhone.setError("Enter lecturer phone number");
facPhone.requestFocus();
}
else if (selectDesign.isEmpty() && selectDesign.equals("Select Designation")){
Toast.makeText(getApplicationContext(), "Select Designation", Toast.LENGTH_SHORT).show();
}
else if (ID.isEmpty()){
facID.setError("Enter lecturer ID");
facID.requestFocus();
}
else{
facReference = FirebaseDatabase.getInstance().getReference().child("Department").child("Lecturer");
String key = facReference.push().getKey();
FacultyConstructor facultyConstructor = new FacultyConstructor(ID, name, intentFac, selectDesign, phone, email, address, "123456", intentMode);
facReference.child(key).setValue(facultyConstructor).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(getApplicationContext(), "Lecturer added successfully", Toast.LENGTH_SHORT).show();
}
}
});
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
if (item.getItemId() == android.R.id.home){
this.finish();
}
return super.onOptionsItemSelected(item);
}
}
I've searched the web and couldn't find a solution.
What I'm trying to do is display a list of an array on the second spinner depending on the selected option from the first spinner.
The logic would be something like this:
If the First spinner = CSE/IT
Then Second Spinner Options would be:
1. BCA 2. MCA
Here's my java code:
public class RegisterActivity extends AppCompatActivity implements View.OnClickListener
{
private EditText TextFname;
private EditText TextMname;
private EditText TextLname;
//private EditText TextDept;
private Spinner SpinDept;
private Spinner SpinProg;
//private EditText TextProg;
private EditText TextSemester;
private EditText TextRolln;
private EditText TextEmail;
private EditText TextPassword;
private EditText TextPasswordConfirm;
//private FirebaseFirestore db = FirebaseFirestore.getInstance();
// Access a Cloud Firestore instance from your Activity
FirebaseFirestore db = FirebaseFirestore.getInstance();
private ProgressBar pBar;
private View bgBlur;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
TextFname = findViewById(R.id.Fname);
TextMname = findViewById(R.id.Mname);
TextLname = findViewById(R.id.Lname);
//TextDept = findViewById(R.id.Dept);
SpinDept = findViewById(R.id.Dept);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.department_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
SpinProg = findViewById(R.id.Prog);
ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(this,
R.array.programme_array, android.R.layout.simple_spinner_item);
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//TextProg = findViewById(R.id.Prog);
TextSemester = findViewById(R.id.Semester);
TextRolln = findViewById(R.id.Rolln);
TextEmail = findViewById(R.id.Email);
TextPassword = findViewById(R.id.Password);
TextPasswordConfirm = findViewById(R.id.PasswordConfirm);
findViewById(R.id.SubmitButton).setOnClickListener(this);
pBar=findViewById(R.id.indeterminateBar);
bgBlur=findViewById(R.id.bgblur);
}
//Validation method
private boolean validate()
{
AwesomeValidation mAwesomeValidation = new AwesomeValidation(BASIC);
mAwesomeValidation.addValidation(TextFname, "\\D+", "Invalid First Name");
mAwesomeValidation.addValidation(TextLname, "\\D+", "Invalid Last Name");
//mAwesomeValidation.addValidation(TextDept, "\\D+", "Invalid Department Name");
//mAwesomeValidation.addValidation(TextProg, "\\D+", "Invalid Programme Name");
mAwesomeValidation.addValidation(TextSemester, "[1-9]+[0-9]{0,}", "Invalid Semester (Cannot be less than 0)");
mAwesomeValidation.addValidation(TextRolln, "[a-zA-Z-0-9\\s]+", "Invalid Roll Number");
mAwesomeValidation.addValidation(TextEmail, Patterns.EMAIL_ADDRESS, "Invalid Email Address");
String regexPassword = "(?=.*[a-z])(?=.*[A-Z])(?=.*[\\d])(?=.*[~`!##\\$%\\^&\\*\\(\\)\\-_\\+=\\{\\}\\[\\]\\|\\;:\"<>,./\\?]).{6,}";
mAwesomeValidation.addValidation(TextPassword, regexPassword, "Use 6 or more characters with a mix of upper & lower letters, numbers & symbols");
mAwesomeValidation.addValidation(TextPasswordConfirm, TextPassword, "Password does not match");
return mAwesomeValidation.validate();
}
#Override
public void onClick(View v)
{
// Check for particular button click, because this method will be called for every
// click on any view on which onClickListener is set as setOnClickListener(this).
// In this case currently it doesn't matter as there is only one button, but in case
// if you also add for example clear field button, then you need to know which
// button was clicked.
switch (v.getId())
{
case R.id.SubmitButton:
if (validate())
{
String TextDept = SpinDept.getSelectedItem().toString();
String TextProg = SpinProg.getSelectedItem().toString();
pBar.setVisibility(View.VISIBLE);
bgBlur.setVisibility(View.VISIBLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
//Toast.makeText(this, "Validation successful", Toast.LENGTH_SHORT).show();
/*String Firstname = getTrimmedInput(TextFname);
String Middlename = getTrimmedInput(TextMname);
String Lastname = getTrimmedInput(TextLname);
String Department = getTrimmedInput(TextDept);
String Programme = getTrimmedInput(TextProg);
String Semester = getTrimmedInput(TextSemester);
String Rollnumber = getTrimmedInput(TextRolln);
String Password = getTrimmedInput(TextPassword);*/
String Email = getTrimmedInput(TextEmail);
final CollectionReference dbUsers = db.collection("Students");
final DocumentReference dbDocs = dbUsers.document(Email);
//Student student = new Student(Firstname, Middlename, Lastname, Department, Programme, Integer.parseInt(Semester), Rollnumber, Email, Password);
//Alternative way how to create data model. I think builder pattern is easier
// to operate as you don't have to know in which order you should pass variables
// (especially when you have a lot of them) to model constructor.
// Although I don't know if my class would work as I don't know how your
// DB backend requests data from your student class as in my model some
// getter method name cases are different. Currently I created my Student
// model as example and it's not used.
final StudentImproved studentImproved = new StudentImproved.Builder()
.setFirstName(getTrimmedInput(TextFname))
.setMiddleName(getTrimmedInput(TextMname))
.setLastName(getTrimmedInput(TextLname))
.setDepartment(TextDept)
.setProgramme(TextProg)
.setSemester(Integer.parseInt(getTrimmedInput(TextSemester)))
.setRollNumber(getTrimmedInput(TextRolln))
.setEmail(getTrimmedInput(TextEmail))
.setPassword(getTrimmedInput(TextPassword))
//.setPasswordConfirm(getTrimmedInput(TextPasswordConfirm))
.build();
dbUsers.document(Email)
.get()
.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>()
{
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task)
{
if (task.isSuccessful())
{
if (task.getResult().exists())
{
pBar.setVisibility(View.GONE);
bgBlur.setVisibility(View.GONE);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
Toast.makeText(RegisterActivity.this, "You already have your data stored in the database", Toast.LENGTH_LONG).show();
}
else
{
dbDocs.set(studentImproved)
.addOnSuccessListener(new OnSuccessListener<Void>()
{
#Override
public void onSuccess(Void aVoid)
{
pBar.setVisibility(View.GONE);
bgBlur.setVisibility(View.GONE);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
Toast.makeText(RegisterActivity.this, "Successfully Registered",Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
pBar.setVisibility(View.GONE);
bgBlur.setVisibility(View.GONE);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
Toast.makeText(RegisterActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
}
});
}
/*else
{
Toast.makeText(this, "Validation failed", Toast.LENGTH_LONG).show();
}
break;*/
}
}
private String getTrimmedInput(EditText text)
{
return text.getText().toString().trim();
}
}
Here's my Spinner XML code:
<Spinner
android:id="#+id/Dept"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="131dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="132dp"
android:entries="#array/department_array"
android:spinnerMode="dropdown"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/Rolln" />
<Spinner
android:id="#+id/Prog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="179dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="180dp"
android:entries="#array/programme_array"
android:spinnerMode="dropdown"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/Dept" />
Here's my String XML Code:
<string-array name="department_array">
<item>Civil</item>
<item>CSE/IT</item>
<item>Electronics</item>
</string-array>
<string-array name="programme_array">
<item>B.Tech Civil</item>
<item>BCA</item>
<item>MCA</item>
</string-array>
spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// load spinner2 data from database method loadData
List<String> spinner2Data= helper.loadData(spinner1.getSelectedItem().toString());
// Create adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(CurrentActivity.this,android.R.layout.simple_spinner_dropdown_item,android.R.id.text1,spinner2Data);
// Drop down layout style - list view with radio button
dataAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinner2.setAdapter(dataAdapter);
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
In the first spinner's setOnItemSelectedListener Load the second spinner based on the ID match or name of department. As you asked where to put setOnItemSelectedListener it should be inside onCreate method the very first method of your activity. For this you can use model classes.
SpinProg = findViewById(R.id.Prog);
SpinDept.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,int position, long arg3) {
programmeArray.clear();
// Here put your logic for selecting programs against each department and initialize programmeArray then load progSpinner with that array
/*
* for(int i=0; i<totalPrograms.size; i++){
*
*
*if(totalPrograms.get(i).getName.equals(totalDepartments.get(position).getName)){
* programmeArray.add(totalPrograms.get(i));
* }
* }
* */
ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(this,
programmeArray, android.R.layout.simple_spinner_item);
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) { }
});
Is it possible to run a date based query from a Firebase database if the date is saved as a String? Or can it be converted? I want to be able to search for records within a particular date range but the dates are saved and retrieved as strings. I use a DatePickerDiaglog to set the date when I add the record. The following is the method for adding a record:
private void addAnimal(){
String breed = editTextBreed.getText().toString().trim();
String gender = spinnerGender.getSelectedItem().toString();
String source = editTextSource.getText().toString().trim();
String DOB = mDisplayDate.getText().toString().trim();
String tag = editTextTagNumber.getText().toString().trim();
if(TextUtils.isEmpty(breed)){
Toast.makeText(this, "You should enter a breed", Toast.LENGTH_LONG).show();
}
else if(TextUtils.isEmpty(source)){
Toast.makeText(this, "You should enter a source", Toast.LENGTH_LONG).show();
}
else if (TextUtils.isEmpty(DOB)){
Toast.makeText(this, "You should enter a Date of Birth", Toast.LENGTH_LONG).show();
}
else if (TextUtils.isEmpty(tag)){
Toast.makeText(this, "You should enter a Tag Number", Toast.LENGTH_LONG).show();
}
else if (tag.length() < 6){
Toast.makeText(this, "Please enter valid tag number", Toast.LENGTH_LONG).show();
}
else{
String id = databaseAnimal.push().getKey();
Animal animal = new Animal(id, breed, gender, source, DOB, tag);
databaseAnimal.child(id).setValue(animal);
Toast.makeText(this, "Animal added", Toast.LENGTH_LONG).show();
} }
This is the code I used to retrieve all the records.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data_retrieved);
listView = findViewById(R.id.list_item);
databaseReference = FirebaseDatabase.getInstance().getReference("animals");
animalList = new ArrayList<>();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String tempListValue =(listView.getItemAtPosition(position).toString());
//String tempListValue = animalList.get(position).toString();
//.get(position).toString();
TextView animalID = (TextView) parent.findViewById(R.id.animalID);
String animalIDText = (String) animalID.getText();
TextView animalGender = (TextView) parent.findViewById(R.id.gender);
String animalGenderText = (String) animalGender.getText();
TextView animalDOB = (TextView) parent.findViewById(R.id.DOB);
String animalDOBText = (String) animalDOB.getText();
TextView source = (TextView) parent.findViewById(R.id.source);
String sourceText = (String) source.getText();
TextView animalBreed = (TextView) parent.findViewById(R.id.breed);
String animalBreedText = (String) animalBreed.getText();
TextView animalTag = (TextView) parent.findViewById(R.id.tag);
String animalTagText = (String) animalTag.getText();
//Multiple Values
Intent intent = new Intent(DataRetrieved.this, ViewAnimalDetails.class);
Bundle extras = new Bundle();
extras.putString("EXTRA_ID",animalIDText);
extras.putString("EXTRA_DOB",animalDOBText);
extras.putString("EXTRA_GENDER",animalGenderText);
extras.putString("EXTRA_SOURCE",sourceText);
extras.putString("EXTRA_BREED", animalBreedText);
extras.putString("EXTRA_TAG", animalTagText);
intent.putExtras(extras);
startActivity(intent);
//intent.putExtra("ListViewClickedValue", tempListValue);
startActivity(intent);
}
}); //List view item click ends
}
#Override
protected void onStart(){
super.onStart();
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot animalSnapshot : dataSnapshot.getChildren()){
Animal animal = animalSnapshot.getValue(Animal.class);
animalList.add(animal);
}
AnimalInfoAdapter animalInfoAdapter = new AnimalInfoAdapter(DataRetrieved.this, animalList);
listView.setAdapter(animalInfoAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Let me know if there is any other information needed, Thanks!
Is it possible to run a date based query from a Firebase database if the date is saved as a string?
The simple answer is yes, you can query based on a String but the results will be wrong. The results that you get when you query literal strings is totally different than the result you get when querying based on Date objects.
Or can it be converted?
Yes it can but the result will be the same as above. The simplest solution to solve this, is to convert the date property from String to Date and query the data according to it.
enter image description hereFirst of all i want to say that my english isn't very good but i hope this is not a problem (i hope). So I wrote a code that "should" get user id from the user of my app but every time
firebase get other id on the same phone can someone help me with this problem ?
If you need more info, please write it in comments . Thank you in advance. Here my code .
EditText editTextName;
Button buttonAdd;
Spinner spinnerGenres;
DatabaseReference databaseArtists;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one_cent);
databaseArtists = FirebaseDatabase.getInstance().getReference("prousers");
editTextName = (EditText) findViewById(R.id.editTextName);
buttonAdd = (Button) findViewById(R.id.buttonAddArtist);
spinnerGenres = (Spinner) findViewById(R.id.spinnerGenres);
buttonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addArtist();
}
});
}
private void addArtist(){
String name = editTextName.getText().toString().trim();
String genre = spinnerGenres.getSelectedItem().toString();
if (!TextUtils.isEmpty(name)){
String id = databaseArtists.push().getKey();
Artist artist = new Artist(id, name, genre);
databaseArtists.child(id).setValue(artist);
Toast.makeText(this, "You are a pro user :D", Toast.LENGTH_LONG).show();
finish();
System.exit(0);
}else{
Toast.makeText(this, "Something's wrong", Toast.LENGTH_LONG).show();
}
}
}
and this one too
public Artist(){
}
public Artist(String artistId, String artistName, String artistGenre) {
this.artistId = artistId;
this.artistName = artistName;
this.artistGenre = artistGenre;
}
public String getArtistId() {
return artistId;
}
public String getArtistName() {
return artistName;
}
public String getArtistGenre() {
return artistGenre;
}
}
I am trying to delete an item from taskList which is connected to sharedPreferences.
I managed to remove all items but the problem is I cant find a way to connect a counter to delete an individual item from a list that has a switch and when this switch is on true I need to remove the item from list by index number.
public class TaskAdapter extends BaseAdapter {
//transfer context
Context context;
//transfer user to use for shared preferences
String userName;
//create a list of tasks.....
List<taskItem> myTasks;
Calendar calendar = Calendar.getInstance();
PendingIntent pendingIntent;
int pos;
//constructor, for creating the adapter we need from the user context and userName
public TaskAdapter(Context context, String userName) {
this.context = context;
this.userName = userName;
//go to user shared preferences and fill the list
getData();
notifyDataSetChanged();
}
//how many item to display
#Override
public int getCount() {
//return the myTasks size....
return myTasks.size();
}
//return a specific item by index
#Override
public Object getItem(int i) {
return myTasks.get(i);
}
//return index number
#Override
public long getItemId(int i) {
return i;
}
//create our view
#Override
public View getView(final int index, final View view, ViewGroup viewGroup) {
//inflate the view inside view object -> viewInflated
final View viewInflated = LayoutInflater.from(context).inflate(R.layout.task_item, null, false);
//set our inflated view behavior
//set pointer for our inflated view
//set pointer for task name....
final TextView txtTaskName = (TextView) viewInflated.findViewById(R.id.taskName);
//set pointer for taskInfo
final TextView txtTaskInfo = (TextView) viewInflated.findViewById(R.id.taskInfo);
//set pointer for task status....
final Switch swTask = (Switch) viewInflated.findViewById(taskDone);
//set task name, by the index of my myTasks collection
txtTaskName.setText(myTasks.get(index).taskName);
//set task info, by index of myTasks collection
txtTaskInfo.setText(myTasks.get(index).taskInfo);
//set task status , switch is getting true/false
swTask.setChecked(myTasks.get(index).taskStatus);
//show date and time dialog
final ImageView dtPicker = (ImageView) viewInflated.findViewById(R.id.imgTime);
dtPicker.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final AlertDialog.Builder ad = new AlertDialog.Builder(context);
final AlertDialog aDialog = ad.create();
final LinearLayout adLayout = new LinearLayout(context);
adLayout.setOrientation(LinearLayout.VERTICAL);
TextView txtTime = new TextView(context);
txtTime.setText("Choose time");
adLayout.addView(txtTime);
final TimePicker tp = new TimePicker(context);
adLayout.addView(tp);
final DatePicker dp = new DatePicker(context);
tp.setVisibility(View.GONE);
adLayout.addView(dp);
final Button btnNext = new Button(context);
btnNext.setText("Next>");
adLayout.addView(btnNext);
btnNext.setGravity(1);
Button btnCancel = new Button(context);
btnCancel.setText("Cancel");
adLayout.addView(btnCancel);
btnCancel.setGravity(1);
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
aDialog.cancel();
}
});
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final int hour = tp.getHour();
final int min = tp.getMinute();
final String myHour = String.valueOf(hour);
final String myMin = String.valueOf(min);
calendar.set(Calendar.MONTH, dp.getMonth());
calendar.set(Calendar.YEAR, dp.getYear());
calendar.set(Calendar.DAY_OF_MONTH, dp.getDayOfMonth());
dp.setVisibility(View.GONE);
tp.setVisibility(View.VISIBLE);
btnNext.setText("Finish");
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
calendar.set(Calendar.HOUR_OF_DAY, tp.getHour());
calendar.set(Calendar.MINUTE, tp.getMinute());
Intent my_intent = new Intent(context, RingtonePlayingService.class);
pendingIntent = PendingIntent.getService(context, 0, my_intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
if(hour > 12){
String myHour = String.valueOf(hour - 12);
}
if(min < 10)
{
String myMin = "0"+String.valueOf(min);
}
Toast.makeText(context, "Set for- "+tp.getHour()+":"+tp.getMinute() , Toast.LENGTH_LONG).show();
aDialog.cancel();
}
});
}
});
aDialog.setView(adLayout);
aDialog.show();
}
});
//create listener event, when switch is pressed
swTask.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//we using utlShared to update task status
//create instance of utlShared
utlShared myShared = new utlShared(context);
//calling method of task, and giving userName(shared preferences, taskName, taskStatus)
myShared.task(userName, txtTaskName.getText().toString(), txtTaskInfo.getText().toString(), swTask.isChecked());
//we sending a message to the user, and inform him/her about the change
Toast.makeText(context, swTask.isChecked() ? "Task done" : "Task undone", Toast.LENGTH_SHORT).show();
}
});
//return the view with the behavior.....
return viewInflated;
}
private void getData() {
//go to specific shared preferences by user name.....
SharedPreferences taskPref = context.getSharedPreferences(userName, context.MODE_PRIVATE);
//create instance of our myTasks list
myTasks = new ArrayList<>();
Map<String, ?> tasks = taskPref.getAll();
for (Map.Entry<String, ?> oneTask : tasks.entrySet()) {
//insert task to list by Key and Value, we check if value is equal to 1, becuase 1=true 0=false
for(int pos=0 ; pos<myTasks.size() ; pos++){
myTasks.get(pos);
}
String[] str = oneTask.getValue().toString().split(",");
myTasks.add(new taskItem(str[0], str[1], str[2].equals("1")));
}
}
}
And my utlShared class is
public class utlShared {
//context to use later
Context context;
//declatrtion of shared preferences object
private SharedPreferences userPref;
//declaration of shared preferences editor
private SharedPreferences.Editor editor;
public utlShared() {}
public utlShared(Context context)
{
//get context to use it
this.context=context;
//declaretion of shared preferences with file name and file mode (private,public)
userPref=context.getSharedPreferences("users",Context.MODE_PRIVATE);
//declaration of editor
editor=userPref.edit();
}
//get user and password
public void addUser(String userName, String password)
{
//stores in the phone device under data\data\package name
//put in shared preferences user name and password
editor.putString(userName,password);
//commit (save/apply) the changes.
editor.commit();
}
public boolean checkUser(String userName)
{
//get name by key->userName
String checkString = userPref.getString(userName,"na");
//print to logcat a custom message.....
Log.e("checkUser", "checkUser: "+checkString );
//check if userName equals to responded data, if it's na, we don't have the user...
return !checkString.equals("na");
}
public boolean checkUserPassword(String userName, String userPassword)
{
String checkString = userPref.getString(userName,"na");
return checkString.equals(userPassword);
}
public void task(String userName,String taskName,String taskInfo, boolean taskDone)
{
//pointer to user task shared preferences
SharedPreferences taskPref=context.getSharedPreferences(userName, Context.MODE_PRIVATE);
//create editor to change the specific shared preferences
SharedPreferences.Editor taskEditor=taskPref.edit();
//add new task -> if true write 1 else write 0
if(!taskDone){
String myData = taskName+","+taskInfo+","+(taskDone?"1":"0");
taskEditor.putString(taskName,myData);
//apply the changes
taskEditor.commit();
}
}
public void clearTasks(String userName, String taskName, String taskInfo, boolean taskDone)
{
SharedPreferences taskPref=context.getSharedPreferences(userName, Context.MODE_PRIVATE);
SharedPreferences.Editor tskEditor=taskPref.edit();
tskEditor.clear();
tskEditor.commit();
}
}
This method is called from my Welcome class which is
public class Welcome extends AppCompatActivity {
String userName;
Context context;
utlShared myUtl;
ListView taskList;
String taskName;
String taskInfo;
boolean taskDone;
AlarmManager alarmManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
setPointer();
}
private void setPointer()
{
this.context=this;
userName=getIntent().getStringExtra("userName");
myUtl = new utlShared(context);
taskList=(ListView)findViewById(R.id.taskList);
setListData();
alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Toast.makeText(Welcome.this, "welcome user:"+userName, Toast.LENGTH_SHORT).show();
Button btnBack = (Button)findViewById(R.id.btnBack);
FloatingActionButton btnDelete=(FloatingActionButton)findViewById(R.id.btnDelete);
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myUtl.clearTasks(userName, taskName, taskInfo, taskDone);
setListData();
}
});
btnBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, MainActivity.class);
startActivity(intent);
finish();
}
});
}
private void setListData() {
final TaskAdapter adapter = new TaskAdapter(context, userName);
taskList.setAdapter(adapter);
}
public void addCustomTask(View view)
{
//create builder
AlertDialog.Builder builder = new AlertDialog.Builder(context);
//set title
builder.setTitle("Add new task!");
//inflate view from layout ->custom layout,null,false as defualt values
View viewInflated= LayoutInflater.from(context).inflate(R.layout.dlg_new_task,null,false);
final EditText txtCustomLine = (EditText)viewInflated.findViewById(R.id.txtHLine);
final EditText txtCustomTask = (EditText)viewInflated.findViewById(R.id.txtTask);
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.setPositiveButton("Add task", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
String myTaskCustom = txtCustomTask.getText().toString();
String myTaskLine = txtCustomLine.getText().toString();
myUtl.task(userName, myTaskCustom, myTaskLine, false);
setListData();
}
});
//display our inflated view in screen
builder.setView(viewInflated);
//show the dialog
builder.show();
}
}
Sorry for the long code but I have spent so much time on that problem and didnt find a normal way to fix it...
Thanks in advance guys, much appreciated!
taskEditor.remove('item tag');
taskEditor.commit();
Guess my question wasnt clear enough but I have found a way to do that.
if(!taskDone){
String myData = taskName+","+taskInfo+","+(taskDone?"1":"0");
taskEditor.putString(taskName,myData);
//apply the changes
taskEditor.commit();
}
else
{
taskEditor.remove(taskName);
taskEditor.commit();
adapter.notifyDataSetChanged();
}
Eventhough its not perfect because I can refresh the view after I update the Editor and only after I restart the app my last deleted tasks disappear.
Cheers and thanks a lot guys!