Reputation: 504
Aim
Allow Users to send reports to the authorities. Reports will be stored and will not be overwritten when new Reports are entered by the same user
Picture of Current Database
The current user signed in is able to store "Incident Report" into the Database but apparently when the user submits another "Incident Report", the newly submitted "Incident Report" will overwrite the data of the previous "Incident Report"
Picture of Desired Database
The Yellow Highlighted data is supposed to be data retrieved from the "Users" child "name" which is the Red Circled data
For example, if the data within the Red Circled data is "Abe Long", the data of the Yellow Highlighted will be "Abe Long" as well.
In addition to that, when the current signed in User submits an "Incident Report", each new one created will create a new Unique Key. This means it will not overwrite the previously submitted data.
Report Fragment Class
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.Date;
import java.util.HashMap;
public class ReportFragment extends Fragment {
private EditText jReportDatePick;
private EditText jReportTimeEnt;
private EditText jReportLocationEnt;
private EditText jReportDescriptionEnt;
private Button jReportSendBtn;
private FirebaseUser jReportCurrentUserID;
private DatabaseReference jReportByUserDatabase;
private ProgressDialog jReportLoad;
public ReportFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View viewRoot = inflater.inflate(R.layout.fragment_report, container, false);
jReportDatePick = viewRoot.findViewById(R.id.reportDatePick);
jReportTimeEnt = viewRoot.findViewById(R.id.reportTimeEnt);
jReportLocationEnt = viewRoot.findViewById(R.id.reportLocationEnt);
jReportDescriptionEnt = viewRoot.findViewById(R.id.reportDescriptionEnt);
jReportSendBtn = viewRoot.findViewById(R.id.reportSendBtn);
jReportLoad = new ProgressDialog(getActivity());
jReportSendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String userReportDate = jReportDatePick.getText().toString();
String userReportTime = jReportTimeEnt.getText().toString();
String userReportLocation = jReportLocationEnt.getText().toString();
String userReportDescription = jReportDescriptionEnt.getText().toString();
if(!TextUtils.isEmpty(userReportDate)&&
!TextUtils.isEmpty(userReportTime)&&
!TextUtils.isEmpty(userReportLocation)&&
!TextUtils.isEmpty(userReportDescription)){
submitReport(userReportDate, userReportTime, userReportLocation, userReportDescription);
jReportLoad.setTitle("Sending Report");
jReportLoad.setMessage("Please wait while the report is being sent");
jReportLoad.setCanceledOnTouchOutside(false);
jReportLoad.show();
}else{
jReportLoad.dismiss();
Toast.makeText(getActivity(), "Report failed to be sent due to empty inputs", Toast.LENGTH_SHORT).show();
}
}
});
return viewRoot;
}
private void submitReport(final String userReportDate,final String userReportTime,
final String userReportLocation,final String userReportDescription) {
jReportCurrentUserID = FirebaseAuth.getInstance().getCurrentUser();
final String reportUserID = jReportCurrentUserID.getUid();
jReportByUserDatabase = FirebaseDatabase.getInstance().getReference().child("Incident Reports").child(reportUserID);
HashMap<String, String> incidentReportUser = new HashMap<>();
incidentReportUser.put("date", userReportDate);
incidentReportUser.put("time", userReportTime);
incidentReportUser.put("location", userReportLocation);
incidentReportUser.put("description", userReportDescription);
jReportByUserDatabase.setValue(incidentReportUser).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
jReportLoad.dismiss();
Toast.makeText(getActivity(), "Report was Sent", Toast.LENGTH_SHORT).show();
jReportDatePick.setText("");
jReportTimeEnt.setText("");
jReportLocationEnt.setText("");
jReportDescriptionEnt.setText("");
}else{
jReportLoad.dismiss();
Toast.makeText(getActivity(), "Report failed to be sent", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Additional Comments
I do not intend for the currently signed in User to be able to submit their name, that will create a possibility of the User entering someone else's name into the "Incident Report". I intend for the "CurrentUser signed in" name to be retrieved and entered into the "Incident Report" automatically.
Instead of putting jReportByUserDatabase.setValue(incidentReportUser)
I have tried putting .updateChildren
while using Map<String, Object>
. The problem was that each data was not entered under a "Unique ID" which will be stored under "Incident Report" within the Data Tree
Solution to the Problem
Helped by both Cadet and JavaBanana
Implementing a "For Loop DataSnapshot" to loop through the data and retrieving the desired one by also using the "Users class" which contains the name, address, status, etc.
private void submitReport(final String userReportDate,final String userReportTime,
final String userReportLocation,final String userReportDescription) {
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference();
dbRef.child("Users").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Users user = snapshot.getValue(Users.class);
HashMap<String, String> incidentReportUser = new HashMap<>();
incidentReportUser.put("name", user.name);
incidentReportUser.put("date", userReportDate);
incidentReportUser.put("time", userReportTime);
incidentReportUser.put("location", userReportLocation);
incidentReportUser.put("description", userReportDescription);
jReportCurrentUserID = FirebaseAuth.getInstance().getCurrentUser();
final String reportUserID = jReportCurrentUserID.getUid();
jReportByUserDatabase = FirebaseDatabase.getInstance().getReference().child("Incident Reports").child(reportUserID);
jReportByUserDatabase.push().setValue(incidentReportUser).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
jReportLoad.dismiss();
Toast.makeText(getActivity(), "Report was Sent", Toast.LENGTH_SHORT).show();
jReportDatePick.setText("");
jReportTimeEnt.setText("");
jReportLocationEnt.setText("");
jReportDescriptionEnt.setText("");
}else{
jReportLoad.dismiss();
Toast.makeText(getActivity(), "Report failed to be sent", Toast.LENGTH_SHORT).show();
}
}
});
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Upvotes: 1
Views: 228
Reputation: 366
Write it by this way (Push adds values, instead of overriding).
jReportByUserDatabase.push()setValue(incidentReportUser)
Also, I recommend to make the Report node containing the user fields also. Like combine them to flat node.
Upvotes: 2
Reputation: 1210
Okay so the main problem with your designs that you are storing the reports under the user's Id which firebase will overwrite obviously.
You can generate a random key for storing your reports and set your report at the generated key in the database.
public class Report {
String reportId; // This is important
String reporterId; //This is important
String reporterName;
String userType;
String status;
String address;
String neibourhood;
String image;
}
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference("Incident Reports");
String reportId = dbRef.push().getKey(); //This generates a new key and returns it
Report report = new Report("report id", "reporter id", "other stuff"... "etc");
dbRef.child(reportId).setValue(report);
To Retrieve the names of the Users
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference();
dbRef.child("Users").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Loop through the retrieved user data
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
System.out.println(user.name);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
Upvotes: 1