I am having an issue with retrieving data from my Firebase database. Please excuse my lack of technial speech as this is not my strong point.
My application is to create a Vehicle listing which posts to a page with a RecyclerView. A new vehicle is added via the "NewVehicle.class" and saved to Firebase underneath an automatically generated node. The user can select a vehicle from the "VehicleList.class" this re-directs them to the "PasswordProtected.class". The user needs to enter a password to view the data relating to the vehicle. Both the vehicle and the "PasswordProtected.class" are linked, or in other words the code knows which vehicle to look at in the database. The user is redirected to the "DataDisplay.class" where they can choose from the graphs they want to view. The issue i am having now is retrieving the specific "VehiclesData" from one vehicle and displaying them in the graph. i have also added an image of what my database looks like in firebase.
NewVehicle.class
public class NewVehicle extends AppCompatActivity
{
//XML variables
private ImageView newVehicleImage;
private EditText vehicleMake, vehicleModel, vehicleReg, password, con_password, engineSize;
private ProgressDialog progress;
private Uri vehicleImage = null;
private StorageReference storageRef;
private DatabaseReference databaseRef;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_vehicle);
storageRef = FirebaseStorage.getInstance().getReference();
databaseRef = FirebaseDatabase.getInstance().getReference().child("Vehicles");
newVehicleImage = findViewById(R.id.new_vehicle_image);
vehicleMake = findViewById(R.id.new_vehicle_make);
vehicleModel = findViewById(R.id.new_vehicle_model);
vehicleReg = findViewById(R.id.new_vehicle_reg);
engineSize = findViewById(R.id.new_vehicle_engine);
Button vehicleAdd = findViewById(R.id.save_btn);
password = findViewById(R.id.password);
con_password = findViewById(R.id.con_password);
progress = new ProgressDialog(this);
newVehicleImage.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
CropImage.activity()
.setGuidelines(CropImageView.Guidelines.ON)
.setMinCropResultSize(512, 512)
.setAspectRatio(1, 1)
.start(NewVehicle.this);
}
});
//When user selects the 'Add' button
vehicleAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
StartPosting();
}
});
}//End onCreate()
private void StartPosting()
{
progress.setMessage("Posting to Vehicle list");
//The make, model and reg is saved to Strings
final String make = vehicleMake.getText().toString().trim();
final String model = vehicleModel.getText().toString().trim();
final String reg = vehicleReg.getText().toString().trim();
final String pass = password.getText().toString().trim();
final String engine = engineSize.getText().toString().trim();
final String con_pass = con_password.getText().toString().trim();
//If the password length is less than six
if(con_pass.length()<6)
{
con_password.setError(getText(R.string.mini_length));
con_password.requestFocus();
}
if(pass.length()<6)
{
password.setError(getText(R.string.mini_length));
password.requestFocus();
}
if(!TextUtils.isEmpty(make) && !TextUtils.isEmpty(model) && !TextUtils.isEmpty(reg) &&
!TextUtils.isEmpty(engine) && !TextUtils.isEmpty(pass) &&
!TextUtils.isEmpty(con_pass) && vehicleImage != null)
{
if (pass.equals(con_pass))
{
progress.show();
StorageReference filePath = storageRef.child("vehicle_images").child(vehicleImage.getLastPathSegment());
filePath.putFile(vehicleImage).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
{
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
{
Uri downloadUrl = taskSnapshot.getDownloadUrl();
DatabaseReference newpost = databaseRef.push();
newpost.child("Make").setValue(make);
newpost.child("Model").setValue(model);
newpost.child("Reg").setValue(reg);
newpost.child("Password").setValue(pass);
newpost.child("Engine").setValue(engine);
newpost.child("Confirmed_Password").setValue(con_pass);
newpost.child("Image").setValue(Objects.requireNonNull(downloadUrl).toString());
progress.dismiss();
startActivity(new Intent(NewVehicle.this, VehicleList.class));
}
});
}
if (!pass.equals(con_pass))
{
Toast.makeText(getApplicationContext(), "Passwords must match", Toast.LENGTH_LONG).show();
}
}
else
{
Toast.makeText(getApplicationContext(), "Fields can not be left empty", Toast.LENGTH_LONG).show();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE)
{
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK)
{
vehicleImage = result.getUri();
newVehicleImage.setImageURI(vehicleImage);
}
//If the resultCode has an error
else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE)
{
Toast.makeText(NewVehicle.this, "Application Error", Toast.LENGTH_LONG).show();
}
}
}
}//End NewVehicle()
VehicleList.class
public class VehicleList extends AppCompatActivity
{
//Declaring RecyclerView
private RecyclerView vehicleList;
//Declaring DatabaseReference to FireBase
private DatabaseReference databaseRef;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Sets the layout according to the XML file
setContentView(R.layout.activity_vehicle_list);
//Linking to the FireBase Real-time Database
databaseRef = FirebaseDatabase.getInstance().getReference().child("Vehicles");
//XML variable
vehicleList = findViewById(R.id.vehicle_list_view);
vehicleList.setHasFixedSize(true);
vehicleList.setLayoutManager(new LinearLayoutManager(this));
FloatingActionButton addVehicleBtn = findViewById(R.id.add_vehicle_btn);
//If the user taps the addPostBtn
addVehicleBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//They will be redirected to the 'NewPost' class where they can add a new post
Intent intent = new Intent(VehicleList.this, NewVehicle.class);
startActivity(intent);
}//End onClick()
});//End addVehicleBtn()
}//End onCreate()
#Override
protected void onStart()
{
super.onStart();
//Recycler Adapter for Vehicles
FirebaseRecyclerAdapter<VehicleLog, VehicleViewHolder> firebaseRecyclerAdapter
= new FirebaseRecyclerAdapter<VehicleLog, VehicleViewHolder>(
VehicleLog.class,
R.layout.vehicle_itemlist,
VehicleViewHolder.class,
databaseRef
){
#Override
protected void populateViewHolder(VehicleViewHolder viewHolder, VehicleLog model, int position)
{
//Get the unique identifier for each record in the database
final String vehicle_key = getRef(position).getKey();
//Gathers the data
viewHolder.setMakeText(model.getMake());
viewHolder.setModelText(model.getModel());
viewHolder.setRegText(model.getReg());
viewHolder.setImage(getApplicationContext(), model.getImage());
//If a record is tapped on
viewHolder.mView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//Users redirected to the next screen
Intent intent = new Intent(VehicleList.this, PasswordProtected.class);
intent.putExtra("Vehicle_id", vehicle_key);
startActivity(intent);
}//End onClick()
});//End OnClickListener()
}//End populateViewHolder()
};//End FirebaseRecyclerAdapter()
vehicleList.setAdapter(firebaseRecyclerAdapter);
}//End onStart()
public static class VehicleViewHolder extends RecyclerView.ViewHolder
{
View mView;
public VehicleViewHolder(View itemView)
{
super(itemView);
mView = itemView;
}//End VehicleViewHolder()
//Sets the vehicles make on screen
public void setMakeText(String make)
{
TextView vehicle_make = mView.findViewById(R.id.vehicle_make);
vehicle_make.setText(make);
}//End setMakeText()
//Sets the vehicles model on screen
public void setModelText(String model)
{
TextView vehicle_model = mView.findViewById(R.id.vehicle_model);
vehicle_model.setText(model);
}//End setModelText()
//Sets the vehicles reg on screen
public void setRegText(String reg)
{
TextView vehicle_reg = mView.findViewById(R.id.vehicle_reg);
vehicle_reg.setText(reg);
}//End setRegText()
//Sets the vehicles image on screen using Glide
public void setImage(Context ctx, String Image)
{
ImageView vehicle_image = mView.findViewById(R.id.post_image);
Glide.with(ctx).load(Image).into(vehicle_image);
}//End setImage()
}//End VehicleViewHolder()
}
PasswordProtected.class
public class PasswordProtected extends AppCompatActivity
{
//Declaring XML variables
private ImageView imageView;
private TextView vehicle_make, vehicle_model;
private EditText ent_pass;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_password_protected);
vehicle_model = findViewById(R.id.model);
vehicle_make = findViewById(R.id.make);
imageView = findViewById(R.id.image);
Button cont = findViewById(R.id.cont);
ent_pass = findViewById(R.id.editTextPassword);
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference().child("Vehicles");
//Gathers the unique key of each record in the database
String vehicle_key =
Objects.requireNonNull(getIntent().getExtras()).getString("Vehicle_id");
databaseRef.child(Objects.requireNonNull(vehicle_key))
.addValueEventListener(new ValueEventListener()
{
public void onDataChange(DataSnapshot dataSnapshot)
{
String model = (String) dataSnapshot.child("Model").getValue();
String make = (String) dataSnapshot.child("Make").getValue();
String image = (String) dataSnapshot.child("Image").getValue();
vehicle_model.setText(model);
vehicle_make.setText(make);
Glide.with(PasswordProtected.this).load(image).into(imageView);
}
#Override
public void onCancelled(DatabaseError databaseError)
{
Toast.makeText(PasswordProtected.this, "Database Error!", Toast.LENGTH_LONG).show();
}
});
cont.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
final String enter_pass = ent_pass.getText().toString().trim();
final DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference().child("Vehicles");
String vehicle_key = Objects.requireNonNull(getIntent().getExtras()).getString("Vehicle_id");
databaseRef.child(Objects.requireNonNull(vehicle_key)).addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot)
{
String pass = (String) dataSnapshot.child("Password").getValue();
Log.v("Firebase:", pass);
if(Objects.equals(pass, enter_pass))
{
Intent intent = new Intent(PasswordProtected.this, DataDisplay.class);
startActivity(intent);
}
else
{
Toast.makeText(getApplicationContext(),"PASSWORD DONT MATCH", Toast.LENGTH_LONG).show();
}//End else()
}//End onDataChange()
public void onCancelled(DatabaseError databaseError)
{
Toast.makeText(PasswordProtected.this, "Database Error!", Toast.LENGTH_LONG).show();
}
});
if(enter_pass.isEmpty())
{
ent_pass.setError(getText(R.string.pass_empt));
ent_pass.requestFocus();
}
if(enter_pass.length()<6)
{
ent_pass.setError(getText(R.string.mini_length));
ent_pass.requestFocus();
}
}
});
}
}
DisplayData.class
public class DataDisplay extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data_display);
//XML variables
Button mass_air = findViewById(R.id.mass_air);
Button engine_load = findViewById(R.id.engine_throttle);
Button engine_RPM = findViewById(R.id.RPM);
Button engine_temps = findViewById(R.id.engine_temps);
mass_air.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent(DataDisplay.this, GraphEngineAirflow.class);
startActivity(intent);
}
});
engine_temps.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent(DataDisplay.this, GraphTempSpecs.class);
startActivity(intent);
}
});
engine_load.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent(DataDisplay.this, GraphEngineSpecs.class);
startActivity(intent);
}
});
engine_RPM.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(DataDisplay.this, GraphEngineRPM.class);
startActivity(intent);
}
});
}
}
GraphEngineAirflow.class
public class GraphEngineAirflow extends Activity implements
OnChartGestureListener, OnChartValueSelectedListener
{
private static final String TAG = "GraphEngineAirflow";
private LineChart chart;
//Array to hold Mass Airflow data from Firebase
ArrayList<Entry> engineAirflow = new ArrayList<>();
//Variables
LineDataSet set1;
LineData data;
protected void onCreate(Bundle savedInstanceState) {
/*This creates an Alert dialog on this screen, it also sets it so the user can cancel the message
for the Mass Airflow rate information*/
AlertDialog.Builder builder = new AlertDialog.Builder(GraphEngineAirflow.this);
builder.setCancelable(true);
//Setting the title and message from the string.xml
builder.setTitle(GraphEngineAirflow.this.getString(R.string.engine_airflow_title));
builder.setMessage(GraphEngineAirflow.this.getString(R.string.engine_airflow_def));
//When the user selects the Cancel button the page will redirect back to the VehicleSpec page
builder.setNegativeButton(GraphEngineAirflow.this.getString(R.string.cancel), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
Intent intent = new Intent(GraphEngineAirflow.this, DataDisplay.class);
startActivity(intent);
}//End onClick()
});//End setNegativeButton()
builder.setPositiveButton(GraphEngineAirflow.this.getString(R.string.Ok), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which)
{
}//End onClick()
});//End setPositiveButton()
builder.show();
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
//Sets the layout according to the XML file
setContentView(R.layout.activity_graph_engine_airflow);
//XML reference
chart = findViewById(R.id.linechart);
//Listens for on chart taps
chart.setOnChartGestureListener(GraphEngineAirflow.this);
chart.setOnChartValueSelectedListener(GraphEngineAirflow.this);
//Enable touch gestures
chart.setTouchEnabled(true);
//Enable scaling and dragging
chart.setDragEnabled(true);
chart.setScaleEnabled(false);
chart.setDrawGridBackground(false);
//Enable pinch zoom
chart.setPinchZoom(true);
//Background color
chart.setBackgroundColor(Color.LTGRAY);
//Setting YAxis
YAxis left = chart.getAxisLeft();
left.setAxisMinimum(0f);
left.setAxisMaximum(50f);
left.setTextSize(13f);
left.enableGridDashedLine(10f, 10f, 0f);
YAxis left2 = chart.getAxisRight();
left2.setEnabled(false);
chart.getAxisRight().setEnabled(false);
//Value string
String[] vals = new String[] {"0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s", "11s"};
//Legend object
Legend i = chart.getLegend();
//Customise legend
i.setTextSize(15f);
i.setForm(Legend.LegendForm.CIRCLE);
i.setTextColor(Color.BLACK);
//Setting XAis
XAxis x = chart.getXAxis();
x.setTextSize(13f);
x.setValueFormatter(new MyXAxisValueFormatter(vals));
x.setGranularity(1);
x.setPosition(XAxis.XAxisPosition.BOTTOM);
//Adding value to array as system will crash without
engineAirflow.add(new Entry(0, 0));
engineAirflow.add(new Entry(1, 0));
//Setting the line
set1 = new LineDataSet(engineAirflow, "Engine AirFlow ");
set1.setFillAlpha(110);
set1.setColor(Color.RED);
set1.setLineWidth(3f);
set1.setValueTextSize(10f);
set1.setValueTextColor(Color.BLACK);
data = new LineData(set1);
chart.setData(data);
//Calls the downloadDatt()
downloadData();
//Change the chart when a change occurs
chart.notifyDataSetChanged();
//XML button
Button checkD = findViewById(R.id.checkdata);
//If the user taps the button
checkD.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
/*This creates an Alert dialog on this screen, it also sets it so the user can cancel the message
for the Mass Airflow rate information retrieved from the database*/
AlertDialog.Builder builder2 = new AlertDialog.Builder(GraphEngineAirflow.this);
builder2.setCancelable(true);
//Setting the title and message from the string.xml
builder2.setTitle(GraphEngineAirflow.this.getString(R.string.IMPORTANT));
builder2.setMessage(GraphEngineAirflow.this.getString(R.string.airflow_info));
//When the user selects the Cancel button the page will redirect back to the VehicleSpec page
builder2.setNegativeButton(GraphEngineAirflow.this.getString(R.string.cancel), new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int whichButton)
{
dialog.cancel();
Intent intent = new Intent(GraphEngineAirflow.this, DataDisplay.class);
startActivity(intent); }//End onClick()
});//End setNegativeButton()
//If the user taps Ok
builder2.setPositiveButton(GraphEngineAirflow.this.getString(R.string.Ok), new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
}//End onClick()
});//End setPositiveButton()
//Show the Dialogs on screen
builder2.show();
}//End onClick()
});//End OnClickListener()
}//End onCreate
//Downloads Data from FireBase
private void downloadData()
{
//ArrayAdapter
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this,R.layout.activity_graph_engine_airflow);
//Connecting into table "VehicleData" on the FireBase database
DatabaseReference database = FirebaseDatabase.getInstance().getReference("Vehicles");
//ChildEventListener allows child events to be listened for
database.addChildEventListener(new ChildEventListener()
{
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey)
{
//Holds the DataSnapshot value of the database as type String
VehicleData vehicleData = dataSnapshot.getValue(VehicleData.class);
//Prints values to console to prove the download is working
System.out.println("getmassAirflowRate: " + Objects.requireNonNull(vehicleData).getMassAirflowRate());
System.out.println("prevChildKey: " + prevChildKey);
System.out.println("data.key" + dataSnapshot.getKey());
//Converting value to integer
setData(Integer.parseInt(dataSnapshot.getKey()), vehicleData);
//Will refresh app when the data changes in the database
arrayAdapter.notifyDataSetChanged();
}//End onChildAdded()
//Will run when data within the database is changed/edited
public void onChildChanged(DataSnapshot dataSnapshot, String s)
{
}//End onChildChanged()
//Will run when data within the database is removed
public void onChildRemoved(DataSnapshot dataSnapshot)
{
}//End onChildRemoved()
//Will run when data within the database is moved to different location
public void onChildMoved(DataSnapshot dataSnapshot, String s)
{
}//End onChildMoved()
//Will run when any sort of error occurs
public void onCancelled(DatabaseError databaseError)
{
}//End onCancelled()
});//End addChildEventListener()
}//End DownloadData()
//Function sets the data on the graph
private void setData(int key, VehicleData vehicleData)
{
//Prints to console first
System.out.println("Using key: " + key);
System.out.println("Setting Mass Intake Airflow Rate: " + vehicleData.getMassAirflowRate());
//Adds new entries to the arrayList and converts the string into a float
engineAirflow.add(new Entry(key + 2, Float.parseFloat(vehicleData.getMassAirflowRate())));
//Change the chart when changes occurs
set1.notifyDataSetChanged();
data.notifyDataChanged();
this.chart.notifyDataSetChanged();
//Redisplay chart
chart.invalidate();
}//End setData()
//Using the String to change the values of the XAis
public class MyXAxisValueFormatter implements IAxisValueFormatter
{
private String[] mVals;
private MyXAxisValueFormatter(String[] vals)
{
this.mVals = vals;
}//End MyXAxisValueFormatter()
#Override
public String getFormattedValue(float value, AxisBase axis)
{
return mVals[(int)value];
}//End getFormattedValue()
}//End MyXAxisValueFormatter()
#Override
//Sends log message if action is performed
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture)
{
Log.i(TAG, "onChartGestureStart: X:" + me.getX() + "Y:" + me.getY());
}//End()
#Override
//Sends log message if action is performed
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture)
{
Log.i(TAG, "onChartGestureEnd: " + lastPerformedGesture);
}//End()
#Override
//Sends log message if action is performed
public void onChartLongPressed(MotionEvent me)
{
Log.i(TAG, "onChartLongPressed: ");
}//End()
#Override
//Sends log message if action is performed
public void onChartDoubleTapped(MotionEvent me)
{
Log.i(TAG, "onChartDoubleTapped: ");
}//End()
#Override
//Sends log message if action is performed
public void onChartSingleTapped(MotionEvent me)
{
Log.i(TAG, "onChartSingleTapped: ");
}//End()
#Override
//Sends log message if action is performed
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY)
{
Log.i(TAG, "onChartFling: veloX: " + velocityX + "veloY" + velocityY);
}//End()
#Override
//Sends log message if action is performed
public void onChartScale(MotionEvent me, float scaleX, float scaleY)
{
Log.i(TAG, "onChartScale: ScaleX: " + scaleX + "ScaleY: " + scaleY);
}//End()
#Override
//Sends log message if action is performed
public void onChartTranslate(MotionEvent me, float dX, float dY)
{
Log.i(TAG, "onChartTranslate: dX" + dX + "dY" + dY);
}//End()
#Override
//Sends log message if action is performed
public void onValueSelected(Entry e, Highlight h) {
Log.i(TAG, "onValueSelected: " + e.toString());
Toast.makeText(this, "onValueSelected: " + e.toString(), Toast.LENGTH_SHORT).show();
}//End()
#Override
//Sends log message if action is performed
public void onNothingSelected() {
Log.i(TAG, "onNothingSelected: ");
}//End()
}//End GraphEngineAirflow()
Change:
DatabaseReference database = FirebaseDatabase.getInstance().getReference("Vehicles").child(vehicle_key).child("Vehicle data");
to,
DatabaseReference database = FirebaseDatabase.getInstance().getReference("Vehicles").child(vehicle_key).child("VehiclesData");
Your code should be fine.
In your First case use reference like this (Not at root directory)
DatabaseReference database = FirebaseDatabase.getInstance().getReference().child("VehicleData").child(your id here mean 0 1 2 how you set that simillarly get as it (check if is not null first) );
you are not referencing to the 0 1 2 3 ids thats mean under the root directory of Vehicle Data you get complete child as value which is not a valid class of VehicleData Class. So you need to move to 0 1 2 3 under which you have a complete class of Vehicle Data
Related
My app has a post layout which have an edit button and the send button. All i want to do is to show only edit button if current user is viewing his/her post and not the send button. Just like a stackoverflow post, you can't edit other's post and can't send a message to yourself. I have tried boolean methods but still no solution. Thanks.
Activity that have showButtonsForCurrentUser() method ;
public class ViewPostActivity extends AppCompatActivity {
private static final String TAG = "ViewPostActivity";
//widgets
private TextView mTitle, mDescription, mPrice, mLocation;
//vars
private String mPostId;
private String userId;
private Post mPost;
private PostImages mPostImages;
private ViewPager viewPager;
private ImageView editPostIcon;
private WormDotsIndicator wormDotsIndicator;
public ViewAdapter viewAdapter;
public DatabaseReference reference;
public FirebaseUser currentUser;
public ArrayList<String> IMAGES = new ArrayList<>();
public ArrayList<Uri> mImageUris = new ArrayList<>();
private SquareImageView postImageView;
private User user;
//Dialog and Sheet vars
private Dialog deleteDialog;
private Button deleteBtnDialog;
private Button deleteBtnSheet;
private Button updateBtn;
private Button sendBtn;
private TextView titleTv, messageTv;
private ImageView closeIcon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_post);
mPostId = getIntent().getStringExtra(getString(R.string.arg_post_id));
mTitle = (TextView) findViewById(R.id.post_title);
mDescription = (TextView) findViewById(R.id.post_description);
mPrice = (TextView) findViewById(R.id.post_price);
mLocation = (TextView) findViewById(R.id.post_location);
postImageView = findViewById(R.id.post_image);
sendBtn = findViewById(R.id.send_msg);
viewPager = findViewById(R.id.view_pager_images);
editPostIcon = findViewById(R.id.edit_post_btn);
wormDotsIndicator = findViewById(R.id.dotsindicator);
editPostIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showBottomSheetDialog();
}
});
getPostInfo();
showButtonsForCurrentUser();
////MyPosts Layout/////
deleteBtnDialog = findViewById(R.id.dialog_btn);
deleteDialog = new Dialog(this);
////MyPosts Layout/////
sendBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(ViewPostActivity.this, MessageActivity.class);
intent.putExtra("userId", userId);
startActivity(intent);
}
});
}
public void showButtonsForCurrentUser(){
currentUser = FirebaseAuth.getInstance().getCurrentUser();
//sendBtn and editPostIcon are set to GONE.
if (currentUser.equals(userId)){
sendBtn.setVisibility(View.VISIBLE);
}else{
editPostIcon.setVisibility(View.VISIBLE);
}
}
private void getPostInfo(){
Log.d(TAG, "getPostInfo: getting the post information.");
reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child(getString(R.string.node_posts))
.orderByKey()
.equalTo(mPostId);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DataSnapshot singleSnapshot = dataSnapshot.getChildren().iterator().next();
if(singleSnapshot != null){
mPost = singleSnapshot.getValue(Post.class);
Log.d(TAG, "onDataChange: found the post: " + mPost.getTitle());
mTitle.setText(mPost.getTitle());
mDescription.setText(mPost.getDescription());
String price = "FREE";
if(mPost.getPrice() != null){
price = "$" + mPost.getPrice();
}
mPrice.setText(price);
String location = mPost.getCity();
mLocation.setText(location);
userId = mPost.getUser_id();
if (mPost.getImage() != null){
wormDotsIndicator.setVisibility(View.INVISIBLE);
postImageView.setVisibility(View.VISIBLE);
Picasso.get().load(mPost.getImage()).into(postImageView);
}else {
IMAGES = mPost.getPostImages();
for (int i = 0; i <IMAGES.size(); i++){
Uri myUri = Uri.parse(IMAGES.get(i));
mImageUris.add(myUri);
}
viewAdapter = new ViewAdapter(getApplication(), IMAGES);
viewPager.setAdapter(viewAdapter);
wormDotsIndicator.setViewPager(viewPager);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void showBottomSheetDialog() {
final BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(ViewPostActivity.this, R.style.BottomSheetDialogTheme);
LinearLayout linearLayout = findViewById(R.id.bottom_sheet_update_container);
View bottomSheetView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.bottom_sheet_update, linearLayout);
updateBtn = bottomSheetView.findViewById(R.id.update_btnn);
deleteBtnSheet = bottomSheetView.findViewById(R.id.delete_btnn);
bottomSheetDialog.setContentView(bottomSheetView);
bottomSheetDialog.show();
updateBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent updateActivityIntent = new Intent(ViewPostActivity.this, UpdateActivity.class);
if (IMAGES != null){
updateActivityIntent.putStringArrayListExtra("IMAGES", IMAGES);
updateActivityIntent.putParcelableArrayListExtra("IMAGEURIS", mImageUris);
}else {
String singlePhotoUrl = mPost.getImage();
updateActivityIntent.putExtra("Single Photo url", singlePhotoUrl);
}
updateActivityIntent.putExtra("Başlık", mTitle.getText());
updateActivityIntent.putExtra("Açıklama", mDescription.getText());
updateActivityIntent.putExtra("Fiyat", mPrice.getText());
updateActivityIntent.putExtra("mPostId", mPostId);
startActivity(updateActivityIntent);
bottomSheetDialog.dismiss();
}
});
deleteBtnSheet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showDeleteDialog();
}
});
}
public void showDeleteDialog(){
deleteDialog.setContentView(R.layout.positive_dialog);
closeIcon = deleteDialog.findViewById(R.id.close_dialog);
deleteBtnDialog = deleteDialog.findViewById(R.id.dialog_btn);
titleTv = deleteDialog.findViewById(R.id.titleTv);
messageTv = deleteDialog.findViewById(R.id.message_dialog);
closeIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
deleteDialog.dismiss();
}
});
deleteDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
deleteDialog.show();
deleteBtnDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
deletePost(mPostId);
finish();
overridePendingTransition( 0, 0);
startActivity(getIntent());
overridePendingTransition( 0, 0);
deleteDialog.dismiss();
}
});
}
private void deletePost(String deletePostId){
Bundle args = new Bundle();
args.putString(getString(R.string.arg_post_id), deletePostId);
Query deleteQuery = reference.child("posts").orderByChild("post_id").equalTo(deletePostId);
deleteQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot delData: dataSnapshot.getChildren()){
delData.getRef().removeValue();
Intent backIntent = new Intent(ViewPostActivity.this, SearchActivity.class);
startActivity(backIntent);
}
Toast.makeText(ViewPostActivity.this,"Data Deleted",Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ViewPostActivity.this,databaseError.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
private void status(String status){
currentUser = FirebaseAuth.getInstance().getCurrentUser();
reference = FirebaseDatabase.getInstance().getReference("users").child(currentUser.getUid());
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("status", status);
reference.updateChildren(hashMap);
}
#Override
protected void onResume() {
super.onResume();
status("online");
}
#Override
protected void onPause() {
super.onPause();
status("offline");
}
}
what are the values for mPostId?
I would log the userID and currentuser values thats being retrieved, to check if there is no issue your query. The boolean part should work
I managed to create the account and authentication when I click on the register button I redirect to login page after that I create a new activity (rdv_detail) which contains a spinner which recovers the values entered names. the problem it is when I create a new account I click on register normally I have to redirect to login page but I redirect to the page (rdv_detail) the spinner managed to recover the value entered at the beginning in the edit text field but when I reconnect by the same user the spinner is empty and I want the spinner to keep all the values entered (name) at the start by the form is there anyone who can help me because I don't know exactly where the error is but I don't have the result I want (account.java -> login.java-> click on a button-> rdv_detail.java (which contains the spinner)
account.java
public class account extends AppCompatActivity {
private EditText nameDoctor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account);
registerButton = findViewById(R.id.btt_register);
nameDoctor = findViewById(R.id.name_doc);
}
//code
private void registerDoctor() {
String name = nameDoctor.getText().toString();
//code
final Doctor doctor = new Doctor(name, city, adress, email, tel, speciality, code);
mAuth.createUserWithEmailAndPassword(doctor.email, password).addOnCompleteListener(new
OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isComplete()) {
Toast.makeText(account.this, "Error ...: " +
task.getException().getMessage(), Toast.LENGTH_LONG).show();
Log.e("doctor", "Error....: " +
task.getException().getMessage());
} else {
Log.e("Adddoctor", "user account created");
new Thread(new Runnable() {
#Override
public void run() {
SaveDoctorData(doctor);
Intent sendNameIntent = new Intent(account.this, rdv_detail.class);
String name=nameDoctor.getText().toString();
sendNameIntent.putExtra("nameDoctor",name);
startActivity(sendNameIntent);
}
}).start();
}
}
});
}
private void SaveDoctorData(Doctor doctor){
db.collection("doctor").add(doctor).addOnCompleteListener(new
OnCompleteListener<DocumentReference>() {
#Override
public void onComplete(#NonNull Task<DocumentReference> task) {
if (!task.isComplete()) {
Toast.makeText(Compte.this, "Error ...: " +
task.getException().getMessage(), Toast.LENGTH_LONG).show();
Log.e("doctor", "Error: " +
task.getException().getMessage());
}else{
Toast.makeText(account.this, " user account created",
Toast.LENGTH_LONG).show();
redirectToLoginPage();
}
}
});
}
private void redirectToLoginPage() {
Intent intent = new Intent(this, login.class);
startActivity(intent);
}
public void cancel(View view) {
redirectToLoginPage();
}
}
rdv_detail.java
//code
public class rdv_detail extends AppCompatActivity implements
DatePickerDialog.OnDateSetListener,TimePickerDialog.OnTimeSetListener,View.OnClickListener{
//code
Spinner spinner_doc;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rdv_detail);
spinner_doc =findViewById(R.id.spinner_doctor);
String nameExtra = getIntent().getStringExtra("nameDoctor");
if(nameExtra !=null)
{
ArrayList<String> spinnerData = new ArrayList<String>();
spinnerData.add(nameExtra);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(rdv_detail.this,
android.R.layout.simple_spinner_item, spinnerData);
spinner_doc.setAdapter(arrayAdapter);
}
}
}
This is my code of how currently/specific logged in users can add to the database, I need help in retrieving the information of these specific user in a listview or recyclerView. I don't want another user to get the data of a different user.
This is also the structure of my database, within the users water bill payment details, the first node generated is the Users ID and also the next node after the Users Id is the transaction id.
Database structure:
mAuth = FirebaseAuth.getInstance();
currentID = mAuth.getCurrentUser().getUid();
databaseWater= FirebaseDatabase.getInstance().getReference().child("users water bill payment details").child(currentID);
progressBar= new ProgressDialog(this);
moneynumberwat = (EditText) findViewById(R.id.moneynumberwat);
moneypinwat = (EditText) findViewById(R.id.moneypinwat);
meterwat = (EditText) findViewById( R.id.meterwat);
user_idwat = (EditText) findViewById(R.id.user_idwat);
amountwat = (EditText) findViewById(R.id.amountwat);
modePaywat = (Spinner) findViewById(R.id.modePaywat);
Paywater = (Button) findViewById(R.id.Paywater);
Paywater.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
addPayWaterInfo();
}
});
setubk();
setupbk();
}
private void setubk() {
ImageButton btn2 = findViewById(R.id.bord);
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
Intent intent = new Intent(PayOffWater.this, Interface.class);
startActivity(intent);
}
});
}
private void setupbk() {
ImageButton btn2 = findViewById(R.id.bak);
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
Intent intent = new Intent(PayOffWater.this, Services.class);
startActivity(intent);
}
});
}
private void addPayWaterInfo() {
String moneynumw = moneynumberwat.getText().toString();
String pincodelitw = moneypinwat.getText().toString();
String meterw = meterwat.getText().toString();
String customerw = user_idwat.getText().toString();
String cashw = amountwat.getText().toString();
String mpayw = modePaywat.getSelectedItem().toString();
if( moneynumw.isEmpty()||moneynumw.length()>10 || moneynumw.length()<10 ||
pincodelitw.length()>4 || pincodelitw.length()<4 ||meterw.isEmpty()||cashw.isEmpty()|| mpayw.isEmpty()){
Toast.makeText(this,"provide correct information before payment can be successful",Toast.LENGTH_LONG).show();
} else{
String id = databaseWater.push().getKey();
com.example.iamstix_jnr.utility.PayOf.Pay pay = new Pay(moneynumw,pincodelitw,meterw,customerw,cashw,mpayw);
databaseWater.child(id).setValue(pay);
finish();
Intent intent = new Intent(PayOffWater.this,Success.class);
startActivity(intent);
}
}
You have to navigate to the last id.
databaseWater= FirebaseDatabase.getInstance().getReference().child("users water bill payment details").child(currentID).child("id of no 3.");
you have to add an ChildEventListener on your database reference and on each callback add or remove or update the adapter that you have on your recyclerview
databaseWater.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
//todo add to adapter
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
//todo update adapter
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
//todo remove from adapter
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
//todo update adapter
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I'm using Firebase to populate my RecyclerView, but the problem is that every time I open the app, I need to swipe down to refresh and then the list of items is available.
Here is my code
public class MainActivity extends AppCompatActivity {
private static final int RC_PHOTO_PICKER = 2;
DatabaseReference db;
FirebaseHelper helper;
MyAdapter adapter;
RecyclerView rv;
EditText nameEditTxt,grpTxt,descTxt,linkTxt;
FirebaseAuth.AuthStateListener authListener;
SwipeRefreshLayout swipeRefresh;
Uri downloadUrl;
String Admin_code;
FirebaseStorage mfirebaseStorage;
private StorageReference mEventPhotoReference;
FloatingActionButton fab;
SharedPreferences sharedPreferences;
ProgressBar spinner;
static boolean calledAlready=false;
public MyAdapter adapter1;
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
spinner = (ProgressBar)findViewById(R.id.progressBar);
spinner.setVisibility(View.GONE);
mfirebaseStorage=FirebaseStorage.getInstance();
if(!calledAlready){
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
calledAlready=true;
}
swipeRefresh=(SwipeRefreshLayout)findViewById(R.id.swiperefresh);
//SETUP RECYCLER
rv = (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
//INITIALIZE FIREBASE DB
db= FirebaseDatabase.getInstance().getReference();
mEventPhotoReference=mfirebaseStorage.getReference().child("Event Photos");
helper=new FirebaseHelper(db);
//ADAPTER
adapter=new MyAdapter(this,helper.retrieve());
rv.setAdapter(adapter);
adapter.notifyDataSetChanged();
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
rv.setAdapter(adapter);
swipeRefresh.setRefreshing(false);
}
});
sharedPreferences= PreferenceManager.getDefaultSharedPreferences(this);
Admin_code=sharedPreferences.getString(getString(R.string.Admin_code),getString(R.string.Admin_default_value));
Log.e("MainActivity","" + Admin_code);
fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
displayInputDialog();
}
});
fab.setVisibility(View.GONE);
showBtn();
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onResume() {
showBtn();
super.onResume();
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void showBtn(){
Admin_code=sharedPreferences.getString(getString(R.string.Admin_code),getString(R.string.Admin_default_value));
if(Objects.equals(Admin_code, "28011996")){
fab.setVisibility(View.VISIBLE);
}
else
fab.setVisibility(View.GONE);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_logout) {
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(MainActivity.this, LoginActivity.class));
return true;
}
if(id==R.id.settings){
Intent settingsIntent=new Intent(this,Settings.class);
startActivity(settingsIntent);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((requestCode& 0xffff) == RC_PHOTO_PICKER && resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
StorageReference photoRef=mEventPhotoReference.child(selectedImageUri.getLastPathSegment());
photoRef.putFile(selectedImageUri)
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// When the image has successfully uploaded, we get its download URL
downloadUrl = taskSnapshot.getDownloadUrl();
Toast.makeText(MainActivity.this,"Photo selected successfully",Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this,"there was a problem uploading photo",Toast.LENGTH_LONG).show();
}
});
}
}
//DISPLAY INPUT DIALOG
private void displayInputDialog()
{
Dialog d=new Dialog(this);
d.setTitle("Save To Firebase");
d.setContentView(R.layout.input_dialog);
nameEditTxt= (EditText) d.findViewById(R.id.nameEditText);
grpTxt= (EditText) d.findViewById(R.id.propellantEditText);
descTxt= (EditText) d.findViewById(R.id.descEditText);
Button saveBtn= (Button) d.findViewById(R.id.saveBtn);
Button photoBtn=(Button)d.findViewById(R.id.photoBtn);
linkTxt = (EditText) d.findViewById(R.id.linkEditText);
photoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), RC_PHOTO_PICKER);
}
});
//SAVE
saveBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//GET DATA
String name=nameEditTxt.getText().toString();
String propellant=grpTxt.getText().toString();
String desc=descTxt.getText().toString();
String link=linkTxt.getText().toString();
Long tsLong = System.currentTimeMillis()/1000;
String ts = tsLong.toString();
//SET DATA
Spacecraft s=new Spacecraft();
s.setName(name);
s.setPropellant(propellant);
s.setDescription(desc);
s.setLink(link);
s.setImageUrl(downloadUrl.toString());
s.setTimestamp(ts);
//SIMPLE VALIDATION
if(name != null && name.length()>0)
{
//THEN SAVE
if(helper.save(s))
{
//IF SAVED CLEAR EDITXT
nameEditTxt.setText("");
grpTxt.setText("");
descTxt.setText("");
linkTxt.setText("");
downloadUrl=null;
adapter=new MyAdapter(MainActivity.this,helper.retrieve());
rv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}else
{
Toast.makeText(MainActivity.this, "Name Must Not Be Empty", Toast.LENGTH_SHORT).show();
}
}
});
d.show();
}
After Searching for a while, I found out that I should use notifyDataSetChanged(); but it doesn't work.
Here is my helper class where I'm fetching data:
public class FirebaseHelper {
DatabaseReference db;
Boolean saved=null;
ArrayList<Spacecraft> spacecrafts=new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//WRITE IF NOT NULL
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;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST
private void fetchData(DataSnapshot dataSnapshot)
{
spacecrafts.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Spacecraft spacecraft=ds.getValue(Spacecraft.class);
spacecrafts.add(spacecraft);
}
}
//READ THEN RETURN ARRAYLIST
public ArrayList<Spacecraft> retrieve() {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
fetchData(dataSnapshot);
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return spacecrafts;
}
It'll be great if someone could help me out here. This is the last problem in my project.
The problem is due to the adapter not knowing about the data that has been fetched asynchronously. Let's try to look at your code step-by-step:
adapter = new MyAdapter(this, helper.retrieve());
helper.retrieve() will initiate an asynchronous request to fetch data from firebase and immediately returns an empty ArrayList (as the data from firebase hasn't reached the app yet).
rv.setAdapter(adapter);
This line sets the adapter to recyclerView, which has an empty arraylist as data, so it won't show anything on the UI.
After the data is received from firebase, ArrayList<Spacecraft> spacecrafts is updated with new data. But the adapter is not notified about this new data. Ideally, adapter.notifyDataSetChanged() should be called after new data is put into the array list.
Hence, when you swipe to refresh after the initial call, the adapter is set to recycler view, leading to an internal call to notifyDataSetChanged(), which in turn loads the new data on to the UI.
Easiest solution is to notify the adapter when new data is received from Firebase. Below is the pseudo code for it -
Create an interface OnFirebaseDataChanged and add a method void dataChanged(); to it.
MainAcitivty should implement this interface and the implementation of that method should call adapter.notifyDataSetChanged()
helper = new FirebaseHelper(db); should be changed to helper = new FirebaseHelper(db, this);
FirebaseHelper's constructor should have a 2nd parameter of type OnFirebaseDataChanged and should save it in a field called dataChangeListener.
Add a line at the end of fetchData method in FirebaseHelper dataChangeListener.dataChanged();
The ideal solution would be to architect the code differently, but that topic is out of scope of this question.
I'm developing an chat app using Firebase as database.
In the app i have 3 activitys: LoginActivity,MainActivity and chatActivity.
In the MainActivity i can open a chat room and then enter to the chat room.
Then it opens the chatActivity.
On the chat activity the users can send message to each other. And here my problem is. When the user type a message and press send. for some reason when the user press the SEND button it jumps to the mainActivity instand send the message. i have no idea whats going on and i need your help guys.
Main activity code
package com.world.bolandian.firebase;
public class MainActivity extends AppCompatActivity {
private Button createChat;
private EditText chatRoomName;
private ListView listView;
private ArrayAdapter<String> arrayAdapter;
private ArrayList<String> listOfChats = new ArrayList<>();
private String name;
private DatabaseReference root = FirebaseDatabase.getInstance().getReference().getRoot();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ifUserIsLoggedIn();
createChat = (Button)findViewById(R.id.createChatBtn);
chatRoomName = (EditText)findViewById(R.id.chatRoomEt);
listView = (ListView)findViewById(R.id.listView);
arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line, listOfChats);
listView.setAdapter(arrayAdapter);
enterUserName();
createChat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Map<String, Object> map = new HashMap<String, Object>();
map.put(chatRoomName.getText().toString(), "");
root.updateChildren(map);
}
});
root.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Set<String> set = new HashSet<String>();
Iterator i = dataSnapshot.getChildren().iterator();
while (i.hasNext()) {
set.add(((DataSnapshot) i.next()).getKey());
}
listOfChats.clear();
listOfChats.addAll(set);
arrayAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(),ChatRoom.class);
intent.putExtra("roomName",((TextView)view).getText().toString());
intent.putExtra("userName",name);
startActivity(intent);
}
});
}
private void ifUserIsLoggedIn(){
FirebaseAuth auth = FirebaseAuth.getInstance();
FirebaseUser user = auth.getCurrentUser();
if(user != null){
}
else
startActivity(new Intent(this,LoginActivity.class));
}
private void enterUserName(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Please enter A nick name:");
final EditText input = new EditText(this);
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
name = input.getText().toString();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
enterUserName();
}
});
builder.show();
}
}
This is ChatActivity
public class ChatRoom extends AppCompatActivity {
private Button sendMessageBtn;
private EditText inputMsg;
private TextView showMessage;
private DatabaseReference root;
private String userName,chatName,tempKey;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_room);
sendMessageBtn = (Button)findViewById(R.id.sendmessagebtn);
inputMsg = (EditText)findViewById(R.id.messageEt);
showMessage = (TextView)findViewById(R.id.showMessage);
userName = getIntent().getExtras().get("userName").toString();
chatName = getIntent().getExtras().get("roomName").toString();
Log.v("username",userName);
Log.v("chatname",chatName);
setTitle(" Room " + chatName);
root = FirebaseDatabase.getInstance().getReference().child(chatName);
sendMessageBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Map<String,Object> map = new HashMap<String, Object>();
tempKey = root.push().getKey();
root.updateChildren(map);
DatabaseReference messageRoot = root.child(tempKey);
Map<String,Object> map2 = new HashMap<String, Object>();
map2.put("name",userName);
map2.put("message",inputMsg);
messageRoot.updateChildren(map2);
}
});
root.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
chatConversation(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
chatConversation(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private String chatMsg,chatUserName;
private void chatConversation(DataSnapshot dataSnapshot){
Iterator i = dataSnapshot.getChildren().iterator();
while(i.hasNext()){
chatMsg = (String)((DataSnapshot)i.next()).getValue();
chatUserName = (String)((DataSnapshot)i.next()).getValue();
showMessage.append(chatUserName + " : " + chatMsg +"\n" );
}
}
}
Thats the code guys
Finally i have found my mistake.
DatabaseReference messageRoot = root.child(tempKey);
Map<String,Object> map2 = new HashMap<String, Object>();
map2.put("name",userName);
map2.put("message",inputMsg); -- thats the line that crash the app
**map2.put("message",inputMsg.getText().toString());** should be like that
messageRoot.updateChildren(map2);