I'm trying to display from data from my Firebase database show in Firebase Recyclerview , This my Database
And i try use the same as tutorial code from
Firebase UI
I'm try and get this result
I'm fairly new to Android and programming in general, so any help would be appreciated. Here is the relevant code.
PostlistFragment
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mActivity = getActivity();
final Dialog mDialog = new Dialog(mActivity, R.style.NewDialog);
mDialog.addContentView(
new ProgressBar(mActivity),
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
);
mDialog.setCancelable(true);
mDialog.show();
// Set up Layout Manager, reverse layout
LinearLayoutManager mManager = new LinearLayoutManager(mActivity);
mManager.setReverseLayout(true);
mManager.setStackFromEnd(true);
mRecycler.setLayoutManager(mManager);
// Set up FirebaseRecyclerAdapter with the Query
Query postsQuery = getQuery(mDatabase);
mAdapter = new FirebaseRecyclerAdapter<PostMainboard, MainboardViewHolder>(PostMainboard.class, R.layout.mainboard_list, MainboardViewHolder.class, postsQuery) {
#Override
public void onDataChanged() {
super.onDataChanged();
mDialog.dismiss();
}
#Override
protected void populateViewHolder(final MainboardViewHolder viewHolder, final PostMainboard model, final int position) {
final DatabaseReference postRef = getRef(position);
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mActivity, MainboardDetailActivity.class);
intent.putExtra(MainboardDetailActivity.EXTRA_POST_KEY, postRef.getKey());
startActivity(intent);
}
});
}
};
mRecycler.setAdapter(mAdapter);
}
#Override
public void onDestroy() {
super.onDestroy();
if (mAdapter != null) {
mAdapter.cleanup();
}
}
public abstract Query getQuery(DatabaseReference databaseReference);
And result of my detail activity got same not show every one
Here My Detail Activity Code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_mainboard_detail);
mBodyView = (TextView)findViewById(R.id.post_detail);
mAuthorView = (TextView)findViewById(R.id.txt_author);
mTitleView = (TextView)findViewById(R.id.post_topic);
mDateView = (TextView)findViewById(R.id.post_date_time);
mCommentsRecycler = (RecyclerView) findViewById(R.id.recycler_comments);
mCommentsRecycler.setLayoutManager(new LinearLayoutManager(this));
mCommentField = (EditText) findViewById(R.id.comment_field);
Button mCommentButton = (Button) findViewById(R.id.button_post_comment);
mCommentButton.setOnClickListener(this);
// Get post key from intent
String mPostKey = getIntent().getStringExtra(EXTRA_POST_KEY);
if (mPostKey == null) {
throw new IllegalArgumentException("Must pass EXTRA_POST_KEY");
}
// Initialize Database
mPostReference = FirebaseDatabase.getInstance().getReference().child("mainboard").child(mPostKey);
mCommentsReference = FirebaseDatabase.getInstance().getReference().child("cm-mainboard").child(mPostKey);
}
#Override
public void onStart() {
super.onStart();
// Add value event listener to the post
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
PostMainboard post = dataSnapshot.getValue(PostMainboard.class);
User user = dataSnapshot.getValue(User.class);
mAuthorView.setText(user.uid);
mTitleView.setText(post.postTopic);
mBodyView.setText(post.postDetail);
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
Toast.makeText(MainboardDetailActivity.this, "Failed to load post.", Toast.LENGTH_SHORT).show();
}
};
mPostReference.addValueEventListener(postListener);
// Keep copy of post listener so we can remove it when app stops
mPostListener = postListener;
// Listen for comments
mAdapter = new CommentAdapter(this, mCommentsReference);
mCommentsRecycler.setAdapter(mAdapter);
}
#Override
public void onStop() {
super.onStop();
if (mPostListener != null) {
mPostReference.removeEventListener(mPostListener);
}
mAdapter.cleanupListener();
}
Post Class
public class PostMainboard{
public String uid;
public String auther;
public String postTopic;
public String postDetail;
public String postImageUrl;
public String postID;
private String postlatlon;
public long timeCreated;
public PostMainboard(){
}
public PostMainboard(String uid, String auther , String postTopic , String postDetail,long timeCreated)
{
this.uid = uid;
this.auther = auther;
this.postTopic = postTopic;
this.postDetail = postDetail;
this.postImageUrl = postImageUrl;
this.postID = postID;
this.timeCreated = timeCreated;
}
#Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put("mb_id", uid);
result.put("mb_auther" , auther);
result.put("mb_title", postTopic);
result.put("mb_body", postDetail);
result.put("mb_create", timeCreated);
return result;
}
User class
public class User {
public String uid;
public String user_fname;
private String user_lname;
private String user_idcard;
private String email;
private String user_phone;
public User(){
}
public User(String uid ,String user_fname, String user_lname, String user_idcard, String email, String user_phone) {
this.uid = uid;
this.user_fname = user_fname;
this.user_lname = user_lname;
this.user_idcard = user_idcard;
this.email = email;
this.user_phone = user_phone;
}
ViewHolder
public class MainboardViewHolder extends RecyclerView.ViewHolder {
private TextView authorView;
private TextView bodyView;
private TextView titleView;
private TextView dateView;
public MainboardViewHolder(View itemView) {
super(itemView);
authorView = (TextView)itemView.findViewById(R.id.txt_author);
bodyView = (TextView)itemView.findViewById(R.id.post_detail);
titleView = (TextView)itemView.findViewById(R.id.post_topic);
dateView = (TextView)itemView.findViewById(R.id.post_date_time);
}
public void bindToPost (PostMainboard postMainboard)
{
authorView.setText(postMainboard.auther);
bodyView.setText(postMainboard.postDetail);
titleView.setText(postMainboard.postTopic);
dateView.setText((int) postMainboard.timeCreated);
}
Mainboard fragment
public class MainboardFragment extends PostListFragment{
public MainboardFragment() {
// Required empty public constructor
}
#Override
public Query getQuery(DatabaseReference databaseReference) {
return databaseReference.child("mainboard").orderByKey();
}
It looks like you have forgotten to populate the ViewHolder (MainboardViewHolder).
In "PostlistFragment" under "populateViewHolder" you need to call viewHolder.bindToPost(model) to bind the data to your textviews and so forth.
Try this:
#Override
protected void populateViewHolder(final MainboardViewHolder viewHolder, final PostMainboard model, final int position) {
final DatabaseReference postRef = getRef(position);
viewHolder.bindToPost(model);
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mActivity, MainboardDetailActivity.class);
intent.putExtra(MainboardDetailActivity.EXTRA_POST_KEY, postRef.getKey());
startActivity(intent);
}
});
}
Also, your getQuery method is abstract and empty. It should probably look like this:
#Override
public Query getQuery(DatabaseReference databaseReference) {
return databaseReference.getReference("mainboard").orderByKey();
}
I'm saying "probably" because I can't see how you have initialized mDatabase. In the future, please paste complete code if you wan't better and faster answers.
Related
The problem is that it always gives "List:NULL" Toast in MainActivity and list is not passed I suppose. Please help, trying for 2 days. Help me!!
I am confused as to how I should pass the ArrayList from Firebase database to my MainActivity.
Before doing the below thing, I tried to pass ArrayList in onCreate of Splash activity after it fetched from firebase but myWebLinks always came null when I used in onCreate except on onDataChange of ValueEventListener so I couldn't pass in next activity.
This is my SplashActivity.class
public class SplashActivity extends AppCompatActivity {
private static final String TAG = "abcd";
//1 Firebase database object
//entry point for the app to access our database
private FirebaseDatabase mFirebaseDatabase;
//2 is a class that reference a specific part of the database, references 'link' portion of DB
private DatabaseReference mDatabaseReference;
//To read from DB, attach ChildEventListener object to the reference. Allows to listen and have code triggered whenever
//changes occur on the node.
private ValueEventListener mValueEventListener;
private AVLoadingIndicatorView aviIV;
private ArrayList<WebLinks> mywebLinks;
public GenericTypeIndicator<ArrayList<WebLinks>> genericTypeIndicator;
private long seed;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
aviIV = findViewById(R.id.avi);
aviIV.smoothToShow();
mFirebaseDatabase = FirebaseDatabase.getInstance();
mDatabaseReference = mFirebaseDatabase.getReference().child("weblinks");
if (mValueEventListener == null) {
valueEventListener();
}
}
#Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause: ");
//14 Removing
if (mValueEventListener != null) {
mDatabaseReference.removeEventListener(mValueEventListener);
mValueEventListener = null;
}
}
#Override
protected void onResume() {
super.onResume();
if (mValueEventListener == null) {
valueEventListener();
mDatabaseReference.addValueEventListener(mValueEventListener);
}
}
void valueEventListener() {
final long[] value = {0};
mValueEventListener = 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.*/
value[0] = dataSnapshot.getChildrenCount();
genericTypeIndicator = new GenericTypeIndicator<ArrayList<WebLinks>>() {
};
mywebLinks = dataSnapshot.getValue(genericTypeIndicator);
seed = System.nanoTime();
Collections.shuffle(mywebLinks, new Random(seed));
Toast.makeText(SplashActivity.this, "" + mywebLinks.get(0).getName(), Toast.LENGTH_SHORT).show();
Log.i(TAG, "getWebLinksFirebaseeee: on");
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
intent.putParcelableArrayListExtra("web_links", mywebLinks);
startActivity(intent);
SplashActivity.this.finish();
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
};
mDatabaseReference.addValueEventListener(mValueEventListener);
}
}
This is my MainActivity.class
public class MainActivity extends AppCompatActivity {
private WebView myWebView;
private WaveSwipeRefreshLayout mWaveSwipeRefreshLayout;
private Toolbar mtoolBar;
private ShineButton mFavBtn;
private BoomMenuButton leftBmb;
public static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
leftBmb = (BoomMenuButton) findViewById(R.id.action_bar_left_bmb);
mFavBtn = (ShineButton) findViewById(R.id.favBtn);
mFavBtn.init(this);
mtoolBar = (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(mtoolBar);
if (getSupportActionBar() != null) {
getSupportActionBar().setElevation(0);
}
ArrayList<WebLinks> myList = getIntent().getParcelableExtra("web_links");
if(myList==null)
Toast.makeText(this, "LIST:NULL", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "LIST:"+myList.get(1).getName(), Toast.LENGTH_SHORT).show();
myWebView = findViewById(R.id.webView);
initWebSettings();
initSwipeRefresh();
initLeftBtn();
}
This is my class
public class WebLinks implements Parcelable {
private String name;
private String link;
public WebLinks() {
}
public WebLinks(String webName, String webLink) {
this.name = webName;
this.link = webLink;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public static final Parcelable.Creator<WebLinks> CREATOR = new Creator<WebLinks>() {
public WebLinks createFromParcel(Parcel source) {
WebLinks fields = new WebLinks();
fields.name = source.readString();
fields.link = source.readString();
return fields;
}
public WebLinks[] newArray(int size) {
return new WebLinks[size];
}
};
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(name);
parcel.writeString(link);
}
}
How can I retrieve my data from firebase to android studio listview? I watch many tutorials on youtube. I use the codes of what did the tutorial gave, but it doesn't work on mine and also every data in my firebase has a unique ID to separate each data.
Here are the codes that I used:
public class ExisActivity extends AppCompatActivity {
private DatabaseReference mdatabase;
private ListView mListView;
private ArrayList<String> marralist = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exis);
mdatabase = FirebaseDatabase.getInstance().getReference();
mListView = (ListView)findViewById(R.id.lvexist);
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,marralist);
mListView.setAdapter(arrayAdapter);
}
}
and this is the other code that i used to get the data:
public class SaveData {
public String getEtOwnername() {
return etOwnername;
}
public void setEtOwnername(String etOwnername) {
this.etOwnername = etOwnername;
}
public String getEtAnimalname() {
return etAnimalname;
}
public void setEtAnimalname(String etAnimalname) {
this.etAnimalname = etAnimalname;
}
public String getEtAddress() {
return etAddress;
}
public void setEtAddress(String etAddress) {
this.etAddress = etAddress;
}
public String getEtContactNo() {
return etContactNo;
}
public void setEtContactNo(String etContactNo) {
this.etContactNo = etContactNo;
}
public String getEtDobAge() {
return etDobAge;
}
public void setEtDobAge(String etDobAge) {
this.etDobAge = etDobAge;
}
public String getEtEmail() {
return etEmail;
}
public void setEtEmail(String etEmail) {
this.etEmail = etEmail;
}
public String getEtClinicalNotes() {
return etClinicalNotes;
}
public void setEtClinicalNotes(String etClinicalNotes) {
this.etClinicalNotes = etClinicalNotes;
}
public String getEtMedication() {
return etMedication;
}
public void setEtMedication(String etMedication) {
this.etMedication = etMedication;
}
public String getEtPayMent() {
return etPayMent;
}
public void setEtPayMent(String etPayMent) {
this.etPayMent = etPayMent;
}
public SaveData(String etOwnername, String etAnimalname, String etAddress, String etContactNo, String etDobAge, String etEmail, String etClinicalNotes, String etMedication, String etPayMent) {
this.etOwnername = etOwnername;
this.etAnimalname = etAnimalname;
this.etAddress = etAddress;
this.etContactNo = etContactNo;
this.etDobAge = etDobAge;
this.etEmail = etEmail;
this.etClinicalNotes = etClinicalNotes;
this.etMedication = etMedication;
this.etPayMent = etPayMent;
}
this is my DB structure of my fire base i'm also new to fire base
{
"rules":{
".read": true,
".write": true,
}
}
Can any help me? please provide some link
PLEASE RESPECT MY POST
I'm developing an app and in first activity it has card view layout. I'm retrieving data from a webservice and relevant data are showed in card view. It's working well. Now when a user clicks a particular card view I need to go for another activity. I'm getting relevant ID for that card view and passing it to the second activity. In second activity I need to show the content according to that unique Id. But I'm not getting any thing. This is what I tried.
Pojo class
public class PromoDetails {
String PromoId;
String PromoName;
String PromoImg;
String promoDetails;
String promoValidty;
public PromoDetails(String PromoId, String PromoName, String PromoImg , String promoDetails , String promoValidity) {
this.PromoId = PromoId;
this.PromoName = PromoName;
this.PromoImg = PromoImg;
this.promoDetails = promoDetails;
this.promoValidty = promoValidity;
}
public String getPromoId() {
return PromoId;
}
public void setPromoId(String promoId) {
PromoId = promoId;
}
public String getPromoName() {
return PromoName;
}
public void setPromoName(String promoName) {
PromoName = promoName;
}
public String getPromoImg() {
return PromoImg;
}
public void setPromoImg(String promoImg) {
PromoImg = promoImg;
}
public String getPromoDetails() {
return promoDetails;
}
public void setPromoDetails(String promoDetails) {
this.promoDetails = promoDetails;
}
public String getPromoValidty() {
return promoValidty;
}
public void setPromoValidty(String promoValidty) {
this.promoValidty = promoValidty;
}}
ApiInterface
public interface ApiInterface {
#POST("ap/promotions.php")
Call<List<Promotions>> getPromotions();
#GET("test.php/promotions/{PromoId}")
Call<List<PromoDetails>> getPromotDetails(#Path("PromoId") String PromoId) ;}
New Activity class
public class PromotionsInside extends Activity {
private ApiInterface apiInterface;
private List<PromoDetails> promoDetails;
TextView prDescription;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.promo_inside);
Bundle extras = getIntent().getExtras();
String promoId = "";
if (extras != null) {
promoId = extras.getString("PROMO_ID");
getPromotionUpdate(promoId);
}
}
private void getPromotionUpdate(String myPromoId) {
apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Call<List<PromoDetails>> call = apiInterface.getPromotDetails(myPromoId);
call.enqueue(new Callback<List<PromoDetails>>() {
#Override
public void onResponse(Call<List<PromoDetails>> call, Response<List<PromoDetails>> response) {
promoDetails = response.body();
runOnUiThread(new Runnable() {
#Override
public void run() {
prDescription = (TextView)findViewById(R.id.promoDescriptionsss) ;
prDescription.setText(promoDetails.get(0).getPromoName());
}
});
}
#Override
public void onFailure(Call<List<PromoDetails>> call, Throwable t) {
}
});
}}
I have similar case. Try to use this to start second activity:
Intent intent = new Intent(this, PromotionsInside.class);
//Make sure that you put String id in intent
intent.putExtra("PROMO_ID", id);
startActivity(intent);
And this in second activity:
if (getIntent().hasExtra("PROMO_ID")) {
String id = getIntent().getStringExtra("PROMO_ID", null);
//next steps that you need
}
Hope it will help you
My goal is to create an app that in basics have two different activities, one in which the user creates a "protocol" (EditorActivity) and on in which the user can view them in a listview(CatalogActivity). If there is something wrong with a protocol, the user must be able to press one of the list view items in the listview, and from there go back in to the EditorActivity and edit the specific item.
My problem is that I have not figured out how to get the old data from the CatalogActivity in to the EditorActivity.
From firebase console:
[Firebase structure][1]
CustomProtocol:
public class CustomProtocol {
public String dateDrill;
public String pileID;
public boolean cleaned;
public CustomProtocol() {
}
public CustomProtocol(String pileID,
String dateDrill,
boolean cleaned) {
this.pileID = pileID;
this.dateDrill = dateDrill;
this.cleaned = cleaned;
}
public void setPileID(String pileID) {
this.pileID = pileID;
}
public String getPileID() {
return pileID;
}
public void setDateDrill(String dateDrill) {
this.dateDrill = dateDrill;
}
public String getDateDrill() {
return dateDrill;
}
}
Snippet from CatalogActivity:
final String projectNumber = projectPrefs.getString(getString(R.string.settings_project_number_key), getString(R.string.settings_project_number_by_default));
mFirebaseDatabase = FirebaseDatabase.getInstance();
mProtocolDatabaseReference = mFirebaseDatabase.getReference().child(projectNumber);
List<CustomProtocol> protocols = new ArrayList<>();
mProtocolAdapter = new ProtocolAdapter(this, R.layout.item_protocol, protocols);
mProtocolListView.setAdapter(mProtocolAdapter);
attachDatabaseReadListener();
mProtocolListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Intent intent = new Intent(CatalogActivity.this, EditorActivity.class);
intent.putExtra("Exiting protocol", EXISTING_PROTOCOL);
}
});
}
EditorActivty:
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
EXISTING_PROTOCOL = intent.getBooleanExtra("Exiting protocol", false);
mEditorFirebaseDatabase = FirebaseDatabase.getInstance();
mEditorProtocolDatabaseReference =
mEditorFirebaseDatabase.getReference().child(projectNumber);
if (EXISTING_PROTOCOL)
mProtocolDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//WHAT GOES HERE SO THAT I CAN POPULATE THE TEXTVIEWS IN THE ACTIVITY_EDITOR WITH THE EXISTING VALUES?
}}
And after this I'm stuck. I guess that I must add something more to the databasereference in the EditorActivity, but I cannot figure out what? Since I don't know the pileID until after the listitem has been clicked? Is there an easier way to do this?
Thank you in advance!
1]: https://i.stack.imgur.com/Bt1mZ.png
You can pass List<CustomProtocol> through intent.
Your CustomProtocol must be implement Parcelable.
Same question is here
1.Make CustomProtocol Parcelable, IDE can do it automatically
public class CustomProtocol implements Parcelable {
public String dateDrill;
public String pileID;
public boolean cleaned;
public CustomProtocol() {
}
public CustomProtocol(String pileID,
String dateDrill,
boolean cleaned) {
this.pileID = pileID;
this.dateDrill = dateDrill;
this.cleaned = cleaned;
}
protected CustomProtocol(Parcel in) {
dateDrill = in.readString();
pileID = in.readString();
cleaned = in.readByte() != 0;
}
public static final Creator<CustomProtocol> CREATOR = new Creator<CustomProtocol>() {
#Override
public CustomProtocol createFromParcel(Parcel in) {
return new CustomProtocol(in);
}
#Override
public CustomProtocol[] newArray(int size) {
return new CustomProtocol[size];
}
};
public void setPileID(String pileID) {
this.pileID = pileID;
}
public String getPileID() {
return pileID;
}
public void setDateDrill(String dateDrill) {
this.dateDrill = dateDrill;
}
public String getDateDrill() {
return dateDrill;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(dateDrill);
parcel.writeString(pileID);
parcel.writeByte((byte) (cleaned ? 1 : 0));
}
}
2.Pass clicked protocol from CatalogActivity to EditorActivity using intent,
mProtocolListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Intent intent = new Intent(CatalogActivity.this, EditorActivity.class);
intent.putExtra("Exiting protocol", EXISTING_PROTOCOL);
intent.putExtra("Clicked protocol object", protocols.get(position));
}
});
3.In editor activity read the clicked protocol though intent.
EXISTING_PROTOCOL = intent.getBooleanExtra("Exiting protocol", false);
protocol = intent.getParcelableExtra("Clicked protocol object");
4.
public void onDataChange(DataSnapshot dataSnapshot) {
//WHAT GOES HERE SO THAT I CAN POPULATE THE TEXTVIEWS IN THE ACTIVITY_EDITOR WITH THE EXISTING VALUES?
// Ans: Find text views by id and set corresponding text from protocol read above.
}}
I'm simply just trying to populate data from Firebase Database into my listview. The logs are showing the data is being retrieved, but the adapter won't set the values to the text in a single list item in the list? All it says is "No setter/field for INSERT VALUE". Which makes me think that I didn't have my setters made correctly but there were auto generated by Android Studio. I don't know what I am missing here. Any help is appreciated.
NODE OBJECT
package com.megliosolutions.ipd.Objects;
import android.graphics.Bitmap;
/**
* Created by Meglio on 6/13/16.
*/
public class NodeObject {
public String mStaticAddress;
public String mLat;
public String mLong;
public NodeObject(){
//needed for firebase
}
public NodeObject(String address, String lat, String Long){
this.mStaticAddress = address;
this.mLat = lat;
this.mLong = Long;
}
public String getmStaticAddress() {
return mStaticAddress;
}
public void setmStaticAddress(String mStaticAddress) {
this.mStaticAddress = mStaticAddress;
}
public String getmLat() {
return mLat;
}
public void setmLat(String mLat) {
this.mLat = mLat;
}
public String getmLong() {
return mLong;
}
public void setmLong(String mLong) {
this.mLong = mLong;
}
}
STATIC LISTADAPTER
/**
* Created by Meglio on 6/14/16.
*/
public class StaticListAdapter extends ArrayAdapter<NodeObject> {
public static String TAG = StaticListAdapter.class.getSimpleName();
public Context mContext;
public List<NodeObject> mNodes;
public class ViewHolder {
TextView mStaticAddress;
TextView mLAT;
TextView mLONG;
}
#Override
public int getCount() {
return mNodes.size();
}
public StaticListAdapter(Context context, List<NodeObject> objects) {
super(context, R.layout.activity_main, objects);
this.mContext = context;
this.mNodes = objects;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
NodeObject node = mNodes.get(position);
if (convertView == null) {
convertView = LayoutInflater.from(this.mContext).inflate(R.layout.node_item, null);
holder.mLONG = (TextView) convertView.findViewById(R.id.node_item_LONG);
holder.mStaticAddress = (TextView) convertView.findViewById(R.id.node_item_IP);
holder.mLAT = (TextView) convertView.findViewById(R.id.node_item_LAT);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mStaticAddress.setText(node.getStaticAddress());
holder.mLONG.setText(node.getLongitude());
holder.mLAT.setText(node.getLatitude());
return convertView;
}
}
MAINACTIVITY
public class MainActivity extends AppCompatActivity {
public static String TAG = MainActivity.class.getSimpleName();
public ListView main_ListView;
public FirebaseAuth mAuth;
public FirebaseUser mUser;
public DatabaseReference mDatabase;
//Strings
public String static_ip;
public String lat = "5.0";
public String mLong = "4.0";
public String currentUser;
//Adapters
public StaticListAdapter listAdapter;
//Node Object
NodeObject node;
public List<NodeObject> nodesList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Instances
mAuth = FirebaseAuth.getInstance();
mUser = mAuth.getCurrentUser();
mDatabase = FirebaseDatabase.getInstance().getReference();
currentUser = mUser.getUid();
main_ListView = (ListView)findViewById(R.id.Main_listview);
//Toolbar
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//[End of Toolbar]
nodesList = new ArrayList<>();
retrieveData();
listAdapter = new StaticListAdapter(getApplicationContext(),nodesList);
main_ListView.setAdapter(listAdapter);
Log.i(TAG, "USER: " + currentUser);
}
private void retrieveData() {
mDatabase.child("nodes").child(mUser.getUid())
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
NodeObject nodeObject = dataSnapshot.getValue(NodeObject.class);
listAdapter.add(nodeObject);
listAdapter.setNotifyOnChange(true);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.getGPS:
//nothing
return true;
case R.id.addNode:
addNode();
return true;
case R.id.logout:
signOut();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void signOut() {
mAuth.signOut();
Intent intent = new Intent(MainActivity.this, Login.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Toast.makeText(getApplicationContext(), "Logging Out.", Toast.LENGTH_SHORT).show();
startActivity(intent);
}
private void addNode() {
//AlertDialog
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle("Dude, assign something...");
LayoutInflater inflater = this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.main_add_node_dialog, null);
dialogBuilder.setView(dialogView);
final EditText editText = (EditText)
dialogView.findViewById(R.id.static_et);
dialogBuilder.setPositiveButton("Assign", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
static_ip = editText.getText().toString();
String ip = static_ip;
node = new NodeObject(ip, lat, mLong);
mDatabase.child("nodes").child(currentUser).push().setValue(node);
Toast.makeText(getApplicationContext(), "Static IP: " + static_ip + " assigned!"
, Toast.LENGTH_SHORT).show();
}
}).
setNegativeButton("Or Not...", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(), "Fine, nvm then..."
, Toast.LENGTH_SHORT).show();
}
});
dialogBuilder.create().show();
}
}
Debugging shows that I am able to get everything client side. Logs show this as well.
06-18 18:25:42.981 12962-12962/com.megliosolutions.ipd D/MainActivity: zHF4TGnRvkeXEbKiLegiUNLGHX12:{-KKLeBAe9pV1Umm3qQMo={mStaticAddress=26161910494949, mLong=3.0, mLat=2.0}, -KKG_ACFvdX7aJOR98-o={mStaticAddress=10.223.22.250, mLong=3.0, mLat=2.0}, -KKWKMZS7WkE_xWbL3rC={mStaticAddress=, mLong=4, mLat=5}, -KKQQLITf9-7iMFlqEWR={mStaticAddress=123123123123, mLong=3.0, mLat=2.0}, -KKG_J6PKwogjBFdk52Z={mStaticAddress=10.333.555.888, mLong=3.0, mLat=2.0}}
UPDATE
The part that didn't make sense to me, but I'm sure makes sense to those who know it very well. Is comprehending what I'm reading the firebase documentation. I read over it a few time, but I guess it just wasn't clicking. I figured out that structuring the data in firebase is KEY. Without that you can't code properly because everything relies on that. Firebase makes it easy to use now that I see it working. I will be making a blog post on this to explain my troubles and how to surpass them so no one else runs into this mess. The below code will build a functional listview with firebase backend!
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
NodeObject nodeObject = dataSnapshot.getValue(NodeObject.class);
listAdapter.add(nodeObject);
listAdapter.setNotifyOnChange(true);
}
In retrieveData(), you should be using a ChildEventListener, not a ValueEventListener. You are adding Node objects as children of node/$uid with the keys generated by push(). The ValueEventListener is returning a Map<String,Object> containing all of the Nodes. That is shown in the logcat output you posted. You can use the onChildAdded() callback of ChildEventListener to get each Node as it is created and then add it to your adapter.
The warning is because the casing mismatches between your field and you setter.
Following the examples in the Firebase documentation, this seems like the better way to model the Java class:
public class NodeObject {
public String staticAddress;
public String lat;
public String lon;
public NodeObject(){
//needed for firebase
}
public NodeObject(String address, String lat, String lon){
this.staticAddress = address;
this.lat = lat;
this.lon = lon;
}
}
As an added bonus this will lead to more sensible JSON property names too.
I had the same issue just now & the answer was pretty frustrating.
I think that the issue is with your naming convention. For example, it looks like you named a variable mLat, and then your accessors/mutators are getmLat() and setmLat(). I think when Firebase is doing the deserialization, they rely on certain naming. For example, if you have a member variable named lat, you will need to have getLat() and setLat().
For your case, you might just be able to change your methods to be getMLat() and setMLat(). Although I'd suggest changing up your conventions a bit in general.
As a side note, know that your naming is typically against convention. Generally, variables prefixed by m are private member variables, accessed & mutated by public methods (like yours).
I was getting an error because I was accessing wrong variable(parent variable)
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
list.add(snapshot.getValue(CategoryModel.class));
// Here in list I should have added dataSnapshot.getValue(CategoryModel.class)
}
}
It may help.