#java #android #firebase #firebase-realtime-database
# #java #Android #firebase #firebase-realtime-database
Вопрос:
Я создаю базовые часы в приложении, я хочу, чтобы сотрудник мог просматривать свои последние смены, поэтому мне нужно получить данные и отсортировать их в таблицу.
Я новичок в firebase и следил за документацией и поиском проблем, с которыми я сталкиваюсь, я hashmap — мой сервер. Отметьте время и поместите его в отдельные места в базе данных firebase, один из которых разогнан, а другой разогнан, под идентификатором сотрудника. Кажется, я просто не могу изменить данные из hashmap в long, а затем отобразить в таблице.
Вот как я hashmap’d и отправил данные в базу данных 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:
Мое лучшее решение побуждает меня игнорировать этот вопрос, но я люблю firebase и думаю, что больше людей должны использовать его, поэтому я сделаю все возможное.
Самый короткий ответ, который я могу дать на ваш вопрос, это «да» и «нет».
Для пояснения короткого ответа мне нужно будет дать гораздо более длинный ответ, который, надеюсь, поможет вам лучше понять направление, в котором вам нужно двигаться, чтобы заставить это работать.
Сначала я подробно остановлюсь на да и нет…
Да: вы можете хранить данные, содержащиеся в Java HashMap, и находить / извлекать их непосредственно из Firebase таким образом, который концептуально очень похож на то, как работает Java HashMap.
Нет: 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 для использования в listview, вам сначала нужно будет поместить их туда, и предоставленный вами код не совсем этого достигнет, но он близок. Итак, сначала вам нужно заставить этот код работать и отправлять данные в firebase.
Одна из моих рекомендаций заключалась бы в том, чтобы после добавления нового элемента в список пользовательских часов либо временно сохранить ключ, сгенерированный firebase для этого тактового времени, локально, либо выполнить поиск позже и использовать его в качестве ключа для соответствующего тактового времени в пользовательском тактовом режиме.out список.
Т.е.
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 и вы готовы извлечь их для своего listview, вы можете вернуть их обратно, используя некоторые из предоставленных фильтров, таких как
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) {
// ...
}
});