Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No setter/field for warning Firebase Database Retrieve Data Populate Listview

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}}

enter image description here

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);
                }
like image 316
wesley franks Avatar asked Jun 18 '16 23:06

wesley franks


3 Answers

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.

like image 160
Bob Snyder Avatar answered Oct 26 '22 23:10

Bob Snyder


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.

like image 29
Frank van Puffelen Avatar answered Oct 27 '22 00:10

Frank van Puffelen


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).

like image 30
poisondminds Avatar answered Oct 27 '22 00:10

poisondminds