简体   繁体   中英

Is it possible to retrieve hash map data from firebase and insert it into a list view?

I'm creating a basic clock in an application, I want the employee to be able to view their recent shifts so I need to retrieve the data and sort it into a table.

I'm new to firebase and have been following the documentation and searching issues I run into, I hashmap's my Server. Timestamp and push it into separate locations in the firebase database one underclocked in and one underclocked out, under the employee ID. I just can't seem to change the data from hashmap to long and then show in the table.

This is how I've hashmap'd and sent the data to the firebase database.

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Initialise Firebase
        FirebaseApp.initializeApp(this);


        //find button
        btn_sign_out = (Button)findViewById(R.id.btn_sign_out);
        btn_sign_out.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Logout
                AuthUI.getInstance()
                        .signOut(MainActivity.this)
                        .addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                btn_sign_out.setEnabled(false);
                                showSignInOptions();
                            }
                        }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Toast.makeText(MainActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                });
                }
            }


        );
        // Assign button variables to the buttons
        btn_clock_in = (Button)findViewById(R.id.btn_clock_in);
        btn_clock_out = (Button)findViewById(R.id.btn_clock_out);
        btn_view_diary = (Button)findViewById(R.id.btn_shift_diaray);

        btn_view_diary.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, shift_diary.class));
            }
        });
        btn_clock_out.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Select Root of Database

                FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                user_information = FirebaseDatabase.getInstance().getReference();
                /*HashMap<String, Object> clockMap = new HashMap<>();

                clockMap.put("Clock out Time" + 1, ServerValue.TIMESTAMP);*/


                user_information.child(user.getUid()).child("Clock_out").push().setValue(clockMap).addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if (task.isSuccessful()){
                            Toast.makeText(MainActivity.this, "Clocked Out Successfully", Toast.LENGTH_SHORT).show();
                            btn_clock_in.setEnabled(true);
                            btn_clock_out.setEnabled(false);
                        } else {
                            Toast.makeText(MainActivity.this, "Clock Out unsuccessful please try again!", Toast.LENGTH_SHORT).show();
                        }
                    }
                });

            }

        });

        btn_clock_in.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Select Root of Database
                user_information = FirebaseDatabase.getInstance().getReference();
                FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

                HashMap<String, Object> dataMap = new HashMap<>();

                dataMap.put("Clock in Time" + 1, ServerValue.TIMESTAMP);

                user_information.child(user.getUid()).child("Clock_In").push().updateChildren(dataMap).addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if (task.isSuccessful()){
                            Toast.makeText(MainActivity.this, "Clocked In Successfully", Toast.LENGTH_SHORT).show();
                            btn_clock_in.setEnabled(false);
                            btn_clock_out.setEnabled(true);
                        } else {
                            Toast.makeText(MainActivity.this, "Clock in unsuccessful please try again!", Toast.LENGTH_SHORT).show();
                        }
                    }
                });

            }
        });`

I have then set the ListView in a separate activity, although I just can't get it to work as it says it can't retrieve the data.

My better judgement is urging me to ignore this question, but I love firebase and think more people should use it so I'll give it my best shot.

The shortest answer I can give to your question is both 'yes' and 'no'.

For clarification of the short answer I'll need to give a much longer answer that will hopefully help you get a better understanding of the direction you need to head to get this working.

First, I'll elaborate on the yes and no thing...

Yes: You can store the data a Java HashMap contains and locate/retrieve it directly from Firebase in a way that is conceptually very similar to the way Java's HashMap operates.

No: Firebase stores JSON documents, not typed objects and data structures specific to an application execution environment, such as your HashMap. Mapping data stored in firebase in to a Java hashmap will require some additional logic

Now, for some actual help with your issue we should start by looking at the data you need to store/use and your current organization paradigm.

Based on the code you have posted combined with some assumption on my part on how you might intend for your code to operate if it were working

user_information.child(user.getUid()).child("Clock_out").push().setValue(clockMap)
user_information.child(user.getUid()).child("Clock_In").push().updateChildren(dataMap)

your data would end up being shaped something like this when viewed as JSON:

{    
       "user_information": 
       {  
           "SomeId1":
           {   
              "Clock_out":  {   "Clock out Time1": "SomeTimestamp",
                                "Clock out Time2": "SomeTimestamp",
                                ...
                                "Clock out TimeN": "SomeTimestamp"   },
              "Clock_In": {  "Clock in Time1": "SomeTimestamp",
                             "Clock in Time2": "SomeTimestamp",
                             ...
                             "Clock in TimeN": "SomeTimestamp"  } 
            }, 
             ...
           "SomeIdN":
           {   
              "Clock_out":  {   "Clock out Time1": "SomeTimestamp",
                                "Clock out Time2": "SomeTimestamp",
                                ...
                                "Clock out TimeN": "SomeTimestamp"   },
              "Clock_In": {  "Clock in Time1": "SomeTimestamp",
                             "Clock in Time2": "SomeTimestamp",
                             ...
                             "Clock in TimeN": "SomeTimestamp"  } 
            }, 
       }
}

Hopefully I'm not too far off target from your organizational construct, and assuming I'm not I'll now tell you that I believe this isn't a fantastic strategy. I base that on past experience having to deal with time tracking software development myself. But, I'll leave it at that and tell you to feel free to ask me for advice on organization techniques only if you want it. However, before you will ever be able to retrieve any data from firebase for use in a listview, you will first need to put it there and the code you've provided won't quite accomplish that, but it's close. So, firstly you'll need to get that code to work and post data to firebase.

One recommendation I have would be to, after pushing a new element to a users clock in list, would be to either temporarily store the key generated by firebase for that clock-in locally or search for it later on and use it as the key for the matching clock-out in a users clock-out list.

IE

String key = user_information.child(user.getUid()).child("Clock_In").push().getKey();   
// key variable now contains an id under which you can store your clock in/out timestamps
user_information.child(user.getUid() + "/Clock_In/" + key).setValue(ServerValue.TIMESTAMP);

And, later on when a clock-out is requested:

// key variable is the same value you were given by firebase during clock-in, you'll need to recall that value somehow
      user_information.child(user.getUid() + "/Clock_out/" + key).setValue(ServerValue.TIMESTAMP);

The reason I recommend this approach is that even though the Clock_out and Clock_in objects behave like lists when dealing with them through firebase they really aren't. They are stored as standard key/value containing objects and retrieving complimentary clock-in/out pairs would be far more efficient if each pair were indexed using the same key.

After you have some data in firebase and are ready to retrieve it for your listview you can pull it back down using some of the filters provided such as

limitToLast()

Full example:

 Query results = user_information.child(user.getUid() + "/Clock_In").limitToLast(10);


results.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
         // Clear your list view, it's about to be repopulated
        for (DataSnapshot clockIn: dataSnapshot.getChildren()) {
             String clockOut = user_information.child(user.getUid() + "/Clock_out/" + clockIn.getKey()).getValue();
             // Add clockIn.getValue() and clockOut to your listview here
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // ...
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM