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

时间:2019-04-15 12:49:50

标签: java android firebase firebase-realtime-database

我正在应用程序中创建一个基本时钟,我希望员工能够查看他们最近的班次,因此我需要检索数据并将其排序到表中。

我是Firebase的新手,一直在关注文档和搜索遇到的问题,我是hashmap的服务器。时间戳记并将其推送到Firebase数据库中位于员工ID下的一个低时时钟和一个低时时钟时钟的单独位置。我只是似乎无法将数据从hashmap更改为long,然后在表中显示。

这是我对数据进行哈希映射并将其发送到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();
                        }
                    }
                });

            }
        });`

然后我将ListView设置在一个单独的活动中,尽管我无法使其正常工作,因为它说它无法检索数据。

1 个答案:

答案 0 :(得分:0)

我更好的判断力是敦促我忽略这个问题,但是我喜欢火力基地,并认为更多的人应该使用它,以便我尽我所能。

对于您的问题,我能给出的最短答案是“是”和“否”。

为了澄清简短的答案,我需要给出更长的答案,希望可以帮助您更好地理解实现此工作所需的方向。

首先,我将详细说明是和否...

是的:您可以存储Java HashMap包含的数据,并从概念上与Java HashMap的操作非常相似的方式直接从Firebase定位/检索。

否:Firebase存储JSON文档,而不存储特定于应用程序执行环境(例如HashMap)的类型化对象和数据结构。将存储在Firebase中的数据映射到Java hashmap中将需要一些额外的逻辑

现在,要获得有关您的问题的实际帮助,我们应该先查看需要存储/使用的数据以及当前的组织范例。

根据您发布的代码,结合我的一些假设(如果代码正常工作,您可能希望代码如何运行)

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

当以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"  } 
            }, 
       }
}

希望我与您的组织结构相差不远,并且假设我不是,我现在告诉您,我认为这不是一个奇妙的策略。我基于过去的经验,必须亲自处理时间跟踪软件开发。但是,我会留在那里,告诉您仅在需要时才向我询问有关组织技术的建议。但是,在您能够从firebase检索任何数据以用于列表视图之前,首先需要将其放在此处,并且您提供的代码还不能完全实现,但是已经接近完成。因此,首先,您需要使该代码正常工作并将数据发布到Firebase。

我的一个建议是,在将新元素推送到用户时钟列表中之后,将临时存储由Firebase为该时钟输入生成的密钥,或者稍后搜索并将其用作用户退出列表中与之匹配的退出键。

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

而且,稍后请求超时时:

// 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);

我之所以推荐这种方法,是因为即使Clock_out和Clock_in对象在通过Firebase处理它们时的行为类似于列表,但实际上并非如此。它们存储为包含标准键/值的对象,如果每对都使用相同的键进行索引,则检索互补的时钟输入/输出对将更加高效。

在Firebase中拥有一些数据并准备为其列表视图检索数据之后,您可以使用提供的某些过滤器(如

)将其拉回
limitToLast()

完整示例:

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