问题
I want to display ListTesting
data sorted by projectName
from the current user
. I try this but it does not work (data not showing):
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list_testing, container, false);
if (getActivity() != null)
Objects.requireNonNull(((AppCompatActivity) getActivity()).getSupportActionBar()).hide();
firebaseAuth = FirebaseAuth.getInstance();
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Users");
Query query = databaseReference.orderByChild("id").equalTo(myId);
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
projectName = "" +dataSnapshot1.child("projectName").getValue();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
//rv and properties
rvListTest = view.findViewById(R.id.rv_postsListTest);
FloatingActionButton fabAddListTest = view.findViewById(R.id.fab_addListTest);
fabAddListTest.setOnClickListener(view1 -> startActivity(new Intent(getActivity(), AddListTestingActivity.class)));
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
//show newest post first
linearLayoutManager.setStackFromEnd(true);
linearLayoutManager.setReverseLayout(true);
//set layout to rv
rvListTest.setLayoutManager(linearLayoutManager);
listTestings = new ArrayList<>();
checkUserStat();
loadPosts();
EditText search_listTest = view.findViewById(R.id.search_listTest);
search_listTest.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
String searchUsers = search_listTest.getText().toString().trim();
if (!searchUsers.isEmpty()){
rvListTest.setVisibility(View.VISIBLE);
searchListTest(charSequence.toString().toLowerCase());
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
return view;
}
private void checkUserStat() {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
myId = user.getUid();
} else {
startActivity(new Intent(getActivity(), ErrorActivity.class));
requireActivity().finish();
}
}
private void loadPosts() { //path of all posts
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("ListTesting");
//query to load posts
Query query = reference.orderByChild("projectName").equalTo(projectName);
//get all data from node Posts
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
listTestings.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ListTesting listTesting = ds.getValue(ListTesting.class);
listTestings.add(listTesting);
//adapter
adapter = new ListTestingAdapter(getActivity(), listTestings);
//set adapter to rv
rvListTest.setAdapter(adapter);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
//if error
Toast.makeText(getActivity(), "" + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}`
回答1:
You can't make a global variable for value in the firebase database, because the database is asynchronous which means there is some time to get the value from the database.
There are two options to solve this:
1- Put the code inside the firebase listener, in your case like this
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Users");
Query query = databaseReference.orderByChild("id").equalTo(myId);
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
projectName = "" +dataSnapshot1.child("projectName").getValue();
}
//then here put your code that exists in loadPosts function
DatabaseReference reference =
FirebaseDatabase.getInstance().getReference("ListTesting");
//query to load posts
Query query = reference.orderByChild("projectName").equalTo(projectName);
//get all data from node Posts
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
listTestings.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ListTesting listTesting = ds.getValue(ListTesting.class);
listTestings.add(listTesting);
//adapter
adapter = new ListTestingAdapter(getActivity(), listTestings);
//set adapter to rv
rvListTest.setAdapter(adapter);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
//if error
Toast.makeText(getActivity(), "" + databaseError.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
2- Create your own callback to wait for Firebase to return your data like this.
Hope this helps you :)
来源:https://stackoverflow.com/questions/62187299/filtering-and-loading-data-compared-value-in-firebase-android