Загрузка данных из Firestore задерживается - PullRequest
0 голосов
/ 03 января 2019

Я хочу отправить array с фрагментом. Доступный массив зависит от извлечения данных из хранилища. Я имею в виду, что элементы массива получены из Firestore. Но получение данных из Firestore становится очень запоздалым, и выполняются следующие строки кода, а также нулевой массив. Что делать, чтобы следующие строки ожидали получения данных из Firestore ??

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {



private static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";
private static final int PERMISSIONS_REQUEST_ENABLE_GPS = 9001;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 9002;
private static final String TAG = "MainActivity";
private static final int ERROR_DIALOG_REQUEST = 9003;
private boolean mLocationPermissionGranted = false;

private List<User>mUserList=new ArrayList<>();
private ArrayList<UserLocation>mUserLocations=new ArrayList<>();

private FusedLocationProviderClient mFusedLocationProviderClient;
FirebaseFirestore mDb;

private GoogleMap mGoogleMap;
private UserLocation mUserPosition=null;
private LatLngBounds latLngBoundary;

private ClusterManager mClusterManager;
private MyClusterManagerRenderer mClusterManagerRenderer;
private ArrayList<ClusterMarker> mClusterMarkers=new ArrayList<>();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mDb = FirebaseFirestore.getInstance();

    initUser();//in this method the data retrieving is implemented

    if (findViewById(R.id.fragment_container) != null) {
        if (savedInstanceState != null) {
            return;
        }            
        MapFragment mapFragment = new MapFragment();
        Bundle bundle=new Bundle();
        bundle.putParcelableArrayList(getString(R.string.userlocations_array),  mUserLocations);
        mapFragment.setArguments(bundle);


        getSupportFragmentManager().beginTransaction()
                .add(R.id.fragment_container, mapFragment).commit();
    }

}

private void initUser() {
    User user=new User();
    user.setEmail("nobeld@gmail.com");
    user.setResponse("ok");
    user.setUser("student");
    user.setUserId("5");
    user.setUserName("nobel");
    ((UserClient)(getApplicationContext())).setUser(user);
    mUserList.add(user);
    User user1=new User();
    user1.setEmail("rahuld@gmail.com");
    user1.setResponse("ok");
    user1.setUser("student");
    user1.setUserId("6");
    user1.setUserName("rahul");
    User user2=new User();
    user2.setEmail("milond@gmail.com");
    user2.setResponse("ok");
    user2.setUser("student");
    user2.setUserId("7");
    user2.setUserName("milon");
    mUserList.add(user1);
    mUserList.add(user2);
    for(User u: mUserList){
        getUserLocation(u);
        //firestore is implemented inside this method
        Log.d(TAG, "initUser: in user array");
    }



}

private void setCameraView(){
    if(mUserPosition!= null){
        Log.d(TAG, "setCameraView: user position got");
        double bottomboundary=mUserPosition.getGeo_point().getLatitude()-.05;
        double leftboundary = mUserPosition.getGeo_point().getLongitude()-.05;
        double upboundary = mUserPosition.getGeo_point().getLatitude()+.05;
        double rightboundary = mUserPosition.getGeo_point().getLongitude()+.05;
        latLngBoundary=new LatLngBounds(new LatLng(bottomboundary,leftboundary),
                new LatLng(upboundary,rightboundary));
        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(latLngBoundary,0));

    }else {
        Log.d(TAG, "setCameraView: user position is null");
    }
}
private void getUserLocation(User user){
    Log.d(TAG, "getUserLocation: ");
    DocumentReference locationRef=mDb.collection(getString(R.string.collection_user_location_student))
            .document(user.getUserId());
    locationRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if(task.isSuccessful()){
                if(task.getResult().toObject(UserLocation.class)!= null){
                    Log.d(TAG, "Location onComplete: ");
                    UserLocation u=task.getResult().toObject(UserLocation.class);
                    mUserLocations.add(u);
                    //here adding the elements to array.

                }else {
                    Log.d(TAG, "onComplete: result is empty");
                }
            }
        }
    });

}

}

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Поскольку данные доступны только внутри метода onComplete() из-за его асинхронного поведения, к тому времени, когда вы пытаетесь добавить список mUserLocations к объекту Bundle, данные еще не закончили загрузку избаза данных и поэтому недоступна (список пуст).Быстрое решение этой проблемы - переместить следующие строки кода:

Bundle bundle=new Bundle();
bundle.putParcelableArrayList(getString(R.string.userlocations_array),  mUserLocations);
mapFragment.setArguments(bundle);

Внутри метода onComplete() сразу после следующей строки кода:

//here adding the elements to array.

Что делать, чтобы следующие строки ожидали получения данных из Firestore ??

Если вы хотите использовать mUserLocations вне этого метода, я рекомендую вам посмотреть последниечасть моего ответа от этой записи , в которой я объяснил, как это можно сделать с помощью пользовательского обратного вызова.Вы также можете взглянуть на это видео для лучшего понимания.

0 голосов
/ 03 января 2019

Эти функции не завершаются сразу;вместо этого они возвращают результаты через предоставленный вами OnCompleteListener callback interface.Это связано с тем, что вашему устройству требуется некоторое время для соединения с сервером, для проверки подлинности и обработки вашего запроса сервером, а также для возврата запрошенных данных.

Если вам необходимо собрать все данные, прежде чем продолжить,Я предлагаю либо переписать ваш запрос, чтобы запросить все необходимые данные сразу (т.е. не отдельные запросы за один раз), затем выполнить ваши последующие шаги после выполнения обратного вызова (то есть вызвать метод в конце обратного вызова)или, альтернативно, выполнив ваш запрос из потока пользовательского интерфейса и используйте synchronization, чтобы заблокировать выполнение вашей задачи до ее завершения.

В любом случае, ваши запросы асинхронные и ваш код пытается сделать что-то полезное в то время, когда он будет ждать ответа.Вот почему он продолжает шагать вперед.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...