Firebase getUid() function only returns NULL - java

PostListFragment is extended by other fragments in my app. I need the uid of the current user, but it always returns null. When I try to run my app, I always get the error:
FATAL EXCEPTION: main
Process: com.example.cleeg.squad, PID: 8524
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
at com.example.cleeg.squad.fragments.PostListFragment.getUid(PostListFragment.java:162)
at com.example.cleeg.squad.fragments.MyPostsFragment.getQuery(MyPostsFragment.java:19)
at com.example.cleeg.squad.fragments.PostListFragment.onActivityCreated(PostListFragment.java:76)
I've tried to find out why this is online, but I just get more confused and I don't really know how to fix it.
The function getUid() is at the bottom of the code.
public abstract class PostListFragment extends Fragment {
private static final String TAG = "PostListFragment";
private DatabaseReference mDatabaseReference;
private FirebaseRecyclerAdapter<Post, PostViewHolder> mAdapter;
private RecyclerView mRecycler;
private LinearLayoutManager mManager;
public PostListFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment_all_posts, container, false);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mRecycler = (RecyclerView) rootView.findViewById(R.id.messages_list);
mRecycler.setHasFixedSize(true);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Set up Layout Manager, reverse layout
mManager = new LinearLayoutManager(getActivity());
mManager.setReverseLayout(true);
mManager.setStackFromEnd(true);
mRecycler.setLayoutManager(mManager);
// Set up FirebaseRecyclerAdapter with the Query
Query postsQuery = getQuery(mDatabaseReference);
mAdapter = new FirebaseRecyclerAdapter<Post, PostViewHolder>(Post.class, R.layout.item_post,
PostViewHolder.class, postsQuery) {
#Override
protected void populateViewHolder(final PostViewHolder viewHolder, final Post model, final int position) {
final DatabaseReference postRef = getRef(position);
// Set click listener for the whole post view
final String postKey = postRef.getKey();
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Launch PostDetailActivity
Intent intent = new Intent(getActivity(), PostDetailActivity.class);
intent.putExtra(PostDetailActivity.EXTRA_POST_KEY, postKey);
startActivity(intent);
}
});
// Determine if the current user has liked this post and set UI accordingly
if (model.stars.containsKey(getUid())) {
viewHolder.starView.setImageResource(R.drawable.ic_toggle_star_24);
} else {
viewHolder.starView.setImageResource(R.drawable.ic_toggle_star_outline_24);
}
// Bind Post to ViewHolder, setting OnClickListener for the star button
viewHolder.bindToPost(model, new View.OnClickListener() {
#Override
public void onClick(View starView) {
// Need to write to both places the post is stored
DatabaseReference globalPostRef = mDatabaseReference.child("posts").child(postRef.getKey());
DatabaseReference userPostRef = mDatabaseReference.child("user-posts").child(model.uid).child(postRef.getKey());
// Run two transactions
onStarClicked(globalPostRef);
onStarClicked(userPostRef);
}
});
}
};
mRecycler.setAdapter(mAdapter);
}
private void onStarClicked(DatabaseReference postRef) {
postRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Post p = mutableData.getValue(Post.class);
if (p == null) {
return Transaction.success(mutableData);
}
if (p.stars.containsKey(getUid())) {
// Unstar the post and remove self from stars
p.starCount = p.starCount - 1;
p.stars.remove(getUid());
} else {
// Star the post and add self to stars
p.starCount = p.starCount + 1;
p.stars.put(getUid(), true);
}
// Set value and report transaction success
mutableData.setValue(p);
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b,
DataSnapshot dataSnapshot) {
// Transaction completed
Log.d(TAG, "postTransaction:onComplete:" + databaseError);
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
if (mAdapter != null) {
mAdapter.cleanup();
}
}
public String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
public abstract Query getQuery(DatabaseReference databaseReference);
}

The crash is because of no user is linked, i.e., getCurrentUser() is null. Please make user you have the user before fetching the userid.
if (FirebaseAuth.getInstance().getCurrentUser() != null) {
mUserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
} else {
//login or register screen
}

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
// User is authenticated and now you can access uesr's properties as followings
mUserID = user.getUid();
} else {
// User is authenticated. So, let's try to re-authenticate
AuthCredential credential = EmailAuthProvider
.getCredential("user#example.com", "password1234");
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d(TAG, "User re-authenticated.");
}
});
}
You can get details on it in this firebase document: https://firebase.google.com/docs/auth/android/manage-users

Related

Match CalendarView value with Firebase date value then show within Recycler/CardView?

I am attempting to implement my own CardView within a Fragment following previous help from another SO user. I think I have done everything correctly however I am not seeing the expected results and think the fault is elsewhere..
What I have is a CalendarView within a Fragment which displays the selected date inside a TextView using setOnDateChangeListener. I then have a hidden RecyclerView which has a CardView within that, which I am trying to call if the CalendarView date matches the date stored in my Firebase database.. Still with me?
I am creating an event schedule, using a form which has event name, date, time, description, all stored as strings, see below:
I have no idea how to retrieve the push() value when referencing my database so I have just used the event name for ease at the moment..
Here is what I have, it is a bit all over the place as I have been testing here and there but please let me know if you have questions.. I tried separating my database references to use them in different areas but this did not work either.
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_schedule, container, false);
intentEvent = getActivity().getIntent().getStringExtra("name");
// ------------- firebase --------------
firebaseAuth = FirebaseAuth.getInstance();
currentUser = firebaseAuth.getCurrentUser();
uid = currentUser.getUid();
databaseReference = FirebaseDatabase.getInstance().getReference("user").child(uid).child("dogs").child(intentEvent);
eventReference = databaseReference.child("events");
dateRef = eventReference.child("date");
// -------------------------------------
calendarView = view.findViewById(R.id.calendarView);
scheduleTitle = view.findViewById(R.id.scheduleTitle);
noEventPlaceholder = view.findViewById(R.id.noEventPlaceholder);
addNewEvent = view.findViewById(R.id.addNewEvent);
eventRecycler = view.findViewById(R.id.eventRecycler);
eventRecycler.setVisibility(View.GONE);
eventLayoutManager = new LinearLayoutManager(getContext());
eventRecycler.setLayoutManager(eventLayoutManager);
FirebaseRecyclerOptions<Event> options
= new FirebaseRecyclerOptions.Builder<Event>()
.setQuery(databaseReference, Event.class)
.build();
eventAdapter = new EventAdapter(options, new EventAdapter.EventCallback() {
#Override
public void onCardViewClick(Event event) {
// view event in full?
}
});
if (eventReference == null) {
addNewEvent.setVisibility(View.VISIBLE);
noEventPlaceholder.setText("Nothing planned for today.. Let's go walkies!");
} else {
eventRecycler.setVisibility(View.VISIBLE);
}
eventRecycler.setAdapter(eventAdapter);
getEventData();
dog = new Dog();
calendarView
.setOnDateChangeListener(
new CalendarView
.OnDateChangeListener() {
#Override
public void onSelectedDayChange(
#NonNull CalendarView view,
int year,
int month,
int dayOfMonth)
{
String date
= dayOfMonth + "-"
+ (month + 1) + "-" + year;
scheduleTitle.setText(date);
}
});
// this is an example of what i am trying to do..
if (String.valueOf(dateRef).equals(scheduleTitle)) {
eventRecycler.setVisibility(View.VISIBLE);
noEventPlaceholder.setText("Nothing planned for today.. Let's go walkies!");
}
// ---------------------------------------------
addNewEvent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue(String.class);
Intent intentEventForm = new Intent(getContext(), EventForm.class);
intentEventForm.putExtra("name", name);
startActivity(intentEventForm);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "onCancelled", databaseError.toException());
}
});
}
});
return view;
}
public void getEventData() {
eventReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String eventName = dataSnapshot.child("name").getValue(String.class);
String eventDate = dataSnapshot.child("date").getValue(String.class);
String eventTime = dataSnapshot.child("time").getValue(String.class);
String eventDescription = dataSnapshot.child("description").getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "onCancelled", databaseError.toException());
}
});
}

parsing string value retrieved by firestore collection to firestore collection

I had users stored in firestore collection under the path users.
i want that query get the data for a users depend on what I put for users.
i.e : I had a students and notification for different stages . if stage second. i retrieve second from getuser() fun then pars it to init() fun. i had tried that but it shows that string value is null
private void init() {
Query query = firebaseFirestore.collection("docs").orderBy("date", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<download> docsFirestoreRecyclerOptions = new FirestoreRecyclerOptions.Builder<download>()
.setQuery(query, download.class)
.build();
adapter = new FirestoreRecyclerAdapter<download, docViewHolder>(docsFirestoreRecyclerOptions) {
#Override
protected void onBindViewHolder(#NonNull final docViewHolder holder, int position, #NonNull final download model) {
//teacher, name, date, url;
holder.teacher.setText(model.getTeacher());
holder.name.setText(model.getName());
holder.date.setText(model.getDate());
holder.url.setText(model.getLink());
holder.btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(),R.string.under_dev, Toast.LENGTH_SHORT).show();
}
});
final String url = holder.url.getText().toString();
holder.doc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);*/
if (url.isEmpty()) {
Toast.makeText(getContext(), "this doesn't contains a link for download", Toast.LENGTH_SHORT).show();
} else {
Intent i = new Intent(v.getContext(), otherUrl.class);
i.putExtra("URL", url);
v.getContext().startActivity(i);
}
}
});
}
#NonNull
#Override
public docViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.downloads, parent, false);
return new docViewHolder(view);
}
};
}
public void checkuser() {
mAuth = FirebaseAuth.getInstance();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
// Name, email address, and profile photo Url
String name = user.getDisplayName();
String email = user.getEmail();
Uri photoUrl = user.getPhotoUrl();
boolean emailVerified = user.isEmailVerified();
// The user's ID, unique to the Firebase project. Do NOT use this value to
// authenticate with your backend server, if you have one. Use
// FirebaseUser.getIdToken() instead.
String uid = user.getUid();
String userId = Objects.requireNonNull(mAuth.getCurrentUser()).getUid().toString();
DocumentReference ref=firebaseFirestore.collection("users").document(userId);
ref.addSnapshotListener(new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(#Nullable DocumentSnapshot value, #Nullable FirebaseFirestoreException error) {
assert value != null;
// docView=value.getString("stage");
textStage.setText(value.getString("stage"));
getStage=value.getString("stage");
}
});
}
}
As per your question, you are saying that you want to fire a query to select a particular user from the database. Is that true?
then
String user - "uid12321";
Query query = firebaseFirestore.collection("docs").collection(user);
Fire above query to get particular user.

Save Boolean state while restarting the application

I have 6 boolean variables which I have initialized as false. There are 6 different imageviews which are associated with these 6 boolean false variables. When the user clicks any of these image, there respective boolean variable is switched to true and when the user again clicks the same image, it will turn to false like on and off. After being satisfied with the selected options, the user can click the done button and the data will be save in the firebase accordingly to whether which options are true and which are false.
My problem is that whenever the application is restarted, all boolean variables are again initialized to false, I understand the fact that, the application restarts for OnCreate class due to which the variables are again false. How can I write a certain code which can save the state of these variables even after application restarts?
Below is my Code:
boolean checkcar = false, checkPickUp = false, checkTruck = false, checkCycle = false, checkBike = false, checkMen = false;
private FirebaseAuth firebaseAuth;
private String currentUserID;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
myTransport = inflater.inflate(R.layout.fragment_transport, container, false);
firebaseAuth = FirebaseAuth.getInstance();
currentUserID = firebaseAuth.getCurrentUser().getUid();
carImage = myTransport.findViewById(R.id.carTransport);
pickUpImage = myTransport.findViewById(R.id.pickUpTransport);
truckImage = myTransport.findViewById(R.id.truckTransport);
cycleImage = myTransport.findViewById(R.id.cyclerTransport);
bikeImage = myTransport.findViewById(R.id.bikeTransport);
menImage = myTransport.findViewById(R.id.menTransport);
done = myTransport.findViewById(R.id.selectUserTransportBtn);
transport = FirebaseDatabase.getInstance().getReference().child("UserProfileDetails").child(currentUserID).child("Transport");
MarkUserRegisteredTransport();
carImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkcar) {
carImage.setColorFilter(carImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkcar = true;
} else {
carImage.setColorFilter(carImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkcar = false;
}
}
});
pickUpImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkPickUp) {
pickUpImage.setColorFilter(pickUpImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkPickUp = true;
} else {
pickUpImage.setColorFilter(pickUpImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkPickUp = false;
}
}
});
truckImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkTruck) {
truckImage.setColorFilter(truckImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkTruck = true;
} else {
truckImage.setColorFilter(truckImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkTruck = false;
}
}
});
cycleImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkCycle) {
cycleImage.setColorFilter(cycleImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkCycle = true;
} else {
cycleImage.setColorFilter(cycleImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkCycle = false;
}
}
});
bikeImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
menImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkMen) {
menImage.setColorFilter(menImage.getContext().getResources().getColor(R.color.TransportAfterClicked), PorterDuff.Mode.SRC_ATOP);
checkMen = true;
} else {
menImage.setColorFilter(menImage.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
checkMen = false;
}
}
});
here is when user can click done and the information is updated in the firebase with true or false with their res
done.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
HashMap userTransport = new HashMap();
userTransport.put("check Car", checkcar);
userTransport.put("check PickUp", checkPickUp);
userTransport.put("check Truck", checkTruck);
userTransport.put("check Cycle", checkCycle);
userTransport.put("check bike", checkBike);
userTransport.put("check Men", checkMen);
transport.updateChildren(userTransport).addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if (task.isSuccessful()) {
Toast.makeText(getContext(), "Transportation information updated", Toast.LENGTH_LONG).show();
} else {
String message = task.getException().getMessage();
Toast.makeText(getContext(), "Error Occured: " + message, Toast.LENGTH_SHORT).show();
}
}
});
}
});
return myTransport;
}
According to your comment:
well i needed the data to be stored even after the user deletes the application just like instagram and facebook
I would like to tell you that either SharedPreferences nor Bundle won't help in this case. Both tehniques when used, do not persist across application uninstalls. If you reinstall the app, your SharedPreferences or your Bundle will be empty and you will not be able to use any data at all.
To solve this, I recommend you add that data to database and everytime the user wants to update his preferences, change the data in database accordingly. So create six new properties of type boolean under your transport object and set/update them accordingly with user's choice.
You can use onSaveInstanceState to save the boolean values, and fetch the values in onCreate or onRestoreInstanceState.
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("boolean1", booleanValue1);
outState.putString("boolean2", booleanValue2); //and so on
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if(savedInstanceState!=null){
if(getString("boolean1") != null){
booleanValue1 = savedInstanceState.getString("boolean1");
}
}
}
Use SharedPreferences, if the application is killed the values saved will not be deleted or reset.
PreferenceManager mManager = PreferenceManager.getDefaultSharedPreferences(context);
//example methods
public static boolean getBool(String resName, boolean defValue) {
return mManager.getBoolean(resName, defValue);
}
public static void setBool(String resName, boolean value) {
mManager.edit()
.putBoolean(resName, value)
.apply();
}
PS: Well, if you uninstall the app or delete the app data (in "Settings", for example) datas will be destroyed

Combining Spinner and Button onClick Listener is giving me a Null Pointer exception

I have an app where a person will be allowed to post an announcement. The person has to select on the spinner the category of their announcement and type their announcement on an EditText. After entering both these fields the Button will allow the person to make the Announcement but if the spinner value or the EditText Value is empty an Error should be generated. I tried making the button invisible for the person typing the Announcement because i was getting a Null Pointer Exception but after switching to, making the button invisible I still get the same Error. This is my Code:
public class MakeAnnouncements extends AppCompatActivity {
private EditText announcement;
private Button announce_button;
private ProgressDialog announcementDialog;
private DatabaseReference mRootRef;
private FirebaseAuth mAuth;
private String mCurrentUserId;
private String announcer;
private String []SPINNERCATEGORY ={"General","Cubs","Scouts","Seniors"};
private String category_text;
private MaterialBetterSpinner betterSpinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_make_announcements);
announcementDialog = new ProgressDialog(this);
mRootRef = FirebaseDatabase.getInstance().getReference();
mAuth = FirebaseAuth.getInstance();
mCurrentUserId = mAuth.getCurrentUser().getUid();
announcement = (EditText)findViewById(R.id.announce_text);
announce_button = (Button)findViewById(R.id.announce_btn);
announce_button.setVisibility(View.VISIBLE);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line,SPINNERCATEGORY);
betterSpinner = (MaterialBetterSpinner)findViewById(R.id.category_spinner);
betterSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
String spinner_value= adapterView.getItemAtPosition(position).toString();
if(position==0){
// no item selected show Toast message
announce_button.setVisibility(View.INVISIBLE);
} else{
announce_button.setVisibility(View.VISIBLE);
// item selected
}
category_text = spinner_value;
return;
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
announce_button.setVisibility(View.INVISIBLE);
}
});
betterSpinner.setAdapter(arrayAdapter);
mRootRef.child("Users").child(mCurrentUserId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
announcer = dataSnapshot.child("name").getValue().toString();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
announce_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) { //<----- This is where i am getting a null point exception
String announced_text = announcement.getText().toString().trim();
String choosen_category = category_text.trim();
if (TextUtils.isEmpty(announced_text)){
announcement.setError("You did not type any announcement");
return;
}
announcementDialog.setTitle("Posting Announcement...");
announcementDialog.setMessage("Please wait...");
announcementDialog.setCanceledOnTouchOutside(false);
announcementDialog.show();
PostAnnouncement(announced_text,choosen_category);
}
});
}
private void PostAnnouncement(String announced_text, String choosen_category) {
DatabaseReference chat_push_key = mRootRef.child("Announcements").child(announcer).push();
String push_key = chat_push_key.getKey();
Map messageMap = new HashMap();
messageMap.put("announcement",announced_text);
messageMap.put("type","text");
messageMap.put("category",choosen_category);
messageMap.put("from",announcer);
messageMap.put("time", ServerValue.TIMESTAMP);
Map messageUserMap = new HashMap();
messageUserMap.put( "Announcements" + "/" + push_key, messageMap);
announcement.setText("");
announcementDialog.hide();
Toast.makeText(getApplicationContext(), "Your announcement was successfully posted",Toast.LENGTH_LONG).show();
mRootRef.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if(databaseError != null){
Log.d("CHAT_LOG", databaseError.getMessage().toString());
}
}
});
}
}
What am i required to do to validate if the spinner Value is not empty?
According to your code you can check on the variable category_text.
if(TextUtils.isEmpty(category_text)){
//Show your error message
}
After checking for possible ways to solve this This Link assisted me.
I first changed the spinner_value to be a global variable. Then wrote this code:
String announced_text = announcement.getText().toString().trim();
String choosen_category = null;
if (TextUtils.isEmpty(announced_text)){
announcement.setError("You did not type any announcement");
return;
}
if(spinner_value != null){
choosen_category = spinner_value.trim();
return;
}
else if(spinner_value == null){
betterspinner.setError("This section must be selected before proceeding");
return;
}
After that i removed button Visibilities that are in my initial code.

List View doesn't populate using Firebase

I am just having a problem when populating my list view. I think I know what's the problem since I tested it multiple times and it seems like the path for retrieving my data is actually the user store and not the bets but I don't seem to get where does the path come from. I was looking back at the methods and it seems that the path would be the DatabaseReference although my reference in the class is just standard
mDatabase = FirebaseDatabase.getInstance().getReference();
Here is my Adapter
public class CustomAdapter extends BaseAdapter{
Context c;
ArrayList<Bets> bets;
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); //Getting currently logged user
DatabaseReference mDatabase;
String hours;
String samount;
public CustomAdapter(Context c, ArrayList<Bets> bets) {
this.c = c;
this.bets = bets;
}
#Override
public int getCount() {
return bets.size();
}
#Override
public Object getItem(int pos) {
return bets.get(pos);
}
#Override
public long getItemId(int itemid) {
return itemid;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
if(view == null)
{
view = LayoutInflater.from(c).inflate(R.layout.item_layout,viewGroup,false);
}
TextView condition = (TextView) view.findViewById(R.id.conditionList);
TextView place = (TextView) view.findViewById(R.id.placeList);
TextView amount = (TextView) view.findViewById(R.id.amountList);
final Bets bet = (Bets) this.getItem(position);
condition.setText(bet.getCondition());
place.setText(bet.getPlace());
String setamount = String.valueOf(bet.getAmount());
amount.setText(setamount);
hours = String.valueOf(bet.getHours());
samount = String.valueOf(bet.getAmount());
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openDetailList(bet.getCreator(),bet.getCondition(),bet.getPlace(),hours,samount,bet.getJoined(),bet.getCreatorUid(),bet.getJoinedUid());
}
});
return view;
}
public void openDetailList(String...details)
{
Intent i = new Intent(c, ListDetail.class);
i.putExtra("CREATOR_KEY",details[0]);
i.putExtra("CONDITION_KEY",details[1]);
i.putExtra("PLACE_KEY",details[2]);
i.putExtra("HOURS_KEY",details[3]);
i.putExtra("AMOUNT_KEY",details[4]);
i.putExtra("JOINED_KEY",details[5]);
i.putExtra("CREATORUID_KEY",details[6]);
i.putExtra("JOINEDUID_KEY",details[7]);
c.startActivity(i);
}
}
and here is my FirebaseHelper
public class FirebaseHelper {
DatabaseReference db;
Boolean saved = null;
ArrayList<Bets> bets = new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
public Boolean save(Bets bets)
{
if(bets == null)
{
saved = false;
}
else {
try {
db.child("bets").push().setValue(bets);
saved = true;
} catch (DatabaseException e) {
e.printStackTrace();
saved = false;
}
}
return saved;
}
private void fetchData(DataSnapshot dataSnapshot)
{
bets.clear();
for(DataSnapshot snapshot: dataSnapshot.getChildren())
{
Bets bet = snapshot.getValue(Bets.class);
bets.add(bet);
}
}
public ArrayList<Bets> 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) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onComplete: Failed=" + databaseError);
}
});
return bets;
}
}
Saving/Inserting data works perfectly fine since I even have a sample data to show you after I added a bet but it doesn't populate the data.
{
"bets" :
{
"-LAzYM9SA-8Sg0YgGqnv" :
{
"amount" : 10,
"condition" : "It will be sunny",
"creator" : "Ginart",
"creatorUid" : "MxQPvCjUIkahVSZk1y2stdCxeY32",
"hours" : 2,
"joined" : "Free",
"joinedUid" : "",
"place" : "New York"
}
For some reason I think it reads the users data which is here
"users" : {
"EbYtfLUPs7Vu2rvnExaOaqJ4J883" : {
"balance" : 5,
"bets" : 1
},
Since every time I add a new user, the list view adds an Item to my list but with no data at all just my template and Android Studio shows me this
W/ClassMapper: No setter/field for balance found on class Models.Bets
W/ClassMapper: No setter/field for bets found on class Models.Bets
So it must be something wrong with the paths in my opinion. My Bets Model has no balance and bets variables.
Here is my OnCreate method where I'm using the retrieve() method in firebase
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logged_in);
Money = (EditText) findViewById(R.id.Balance);
User = (EditText) findViewById(R.id.Player);
betList = (ListView) findViewById(R.id.BetList);
addbet = (FloatingActionButton) findViewById(R.id.AddBet);
addcreds = (TextView) findViewById(R.id.addCredits);
Money.setInputType(0);
User.setInputType(0);
betting = FirebaseDatabase.getInstance().getReference();
mDatabase = FirebaseDatabase.getInstance().getReference();
helper = new FirebaseHelper(betting);
mDatabase.child("users").child(current.getUid().toString()).child("balance").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
balance = dataSnapshot.getValue(Long.class);
String b = String.valueOf(balance);
Money.setText(b);
}
#Override
public void onCancelled(DatabaseError error) {
Money.setText("Error");
}
});
mDatabase.child("users").child(current.getUid().toString()).child("bets").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
bets = dataSnapshot.getValue(Long.class);
}
#Override
public void onCancelled(DatabaseError error) {
}
});
User.setText(current.getDisplayName().toString());
//ADAPTER
adapter = new CustomAdapter(this,helper.retrieve());
betList.setAdapter(adapter);
addbet.setOnClickListener(this);
addcreds.setOnClickListener(this);
}
Also, whenever I'm trying to change my reference to
betting = FirebaseDatabase.getInstance().getReference().child("bets");
I get this error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.betme.betme, PID: 22814
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type Models.Bets
at com.google.android.gms.internal.zg.zzb(Unknown Source)
at com.google.android.gms.internal.zg.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at Utils.FirebaseHelper.fetchData(FirebaseHelper.java:67)
at Utils.FirebaseHelper.access$000(FirebaseHelper.java:21)
at Utils.FirebaseHelper$1.onChildAdded(FirebaseHelper.java:81)
at com.google.android.gms.internal.px.zza(Unknown Source)
at com.google.android.gms.internal.vj.zzHX(Unknown Source)
at com.google.android.gms.internal.vp.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
It's not error, It's just a waring from Firebase that you should have methods to set data for balance and bets

Categories

Resources