简体   繁体   English

是否可以从firebase检索哈希映射数据并将其插入列表视图?

[英]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. 我是firebase的新手,并且一直在关注我遇到的文档和搜索问题,我的hashmap是我的服务器。 Timestamp and push it into separate locations in the firebase database one underclocked in and one underclocked out, under the employee ID. 时间戳并将其推送到firebase数据库中的一个位置,一个在同一个位置,一个是在员工ID下面的一个低频输出。 I just can't seem to change the data from hashmap to long and then show in the table. 我似乎无法将数据从hashmap更改为long然后显示在表中。

This is how I've hashmap'd and sent the data to the firebase database. 这就是我对hashmap并将数据发送到firebase数据库的方式。

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. 然后我将ListView设置在一个单独的活动中,虽然我无法让它工作,因为它说它无法检索数据。

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. 我更好的判断力是敦促我忽略这个问题,但是我喜欢firebase,并且认为更多的人应该使用它,所以我会尽我所能。

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. 是:您可以存储Java HashMap包含的数据,并直接从Firebase定位/检索它,其概念与Java的HashMap操作方式非常相似。

No: Firebase stores JSON documents, not typed objects and data structures specific to an application execution environment, such as your HashMap. 否:Firebase存储JSON文档,而不是特定于应用程序执行环境的类型化对象和数据结构,例如HashMap。 Mapping data stored in firebase in to a Java hashmap will require some additional logic 将存储在firebase中的数据映射到Java hashmap将需要一些额外的逻辑

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: 当您将数据视为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. 但是,在您能够从firebase中检索任何数据以便在列表视图中使用之前,您首先需要将它放在那里,而您提供的代码将无法完成,但它已经接近了。 So, firstly you'll need to get that code to work and post data to firebase. 所以,首先你需要让代码工作并将数据发布到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. 在将新元素推送到列表中的用户时钟之后,我将提出的一个建议是,在本地临时存储firebase为该时钟生成的密钥,或者稍后搜索它并将其用作密钥。用户时钟输出列表中的匹配时钟输出。

IE 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. 我推荐这种方法的原因是,即使Clock_out和Clock_in对象在通过firebase处理它们时表现得像列表,它们实际上也不是。 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 在firebase中有一些数据并准备好为列表视图检索它之后,您可以使用提供的一些过滤器将其拉回来,例如

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) {
        // ...
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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