Home > Net >  Impossible to get out of "gsReference.getFile(Objects.requireNonNull(localFile)).addOnSuccessLi
Impossible to get out of "gsReference.getFile(Objects.requireNonNull(localFile)).addOnSuccessLi

Time:09-23

I am trying to get a value from the first line of a csv file ( header excluded) store in Firebase Storage

Here is the code :

private String readFromCsv() {

    StorageReference refCompteActifs = FirebaseStorage.getInstance().getReference().child("my_file").child("my_file.csv");
    StorageReference gsReference = refCompteActifs.getStorage().getReferenceFromUrl("gs://test-8095e.appspot.com/my_file/my_filer.csv");
    File localFile = null;
    try {
        localFile = File.createTempFile("my_file", ".csv");
    } catch (IOException e) {
        e.printStackTrace();
    }
    File finalLocalFile = localFile;
    final String[] result = {null};
    List<String> rows = new ArrayList<>();
    gsReference.getFile(Objects.requireNonNull(localFile)).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
            try {
                CSVReader reader = new CSVReader(new FileReader("./data/user/0/com.example.test/cache/"   finalLocalFile.getName()), ',', '\'', 1);
                String[] nextLine = null;

                while ((nextLine = reader.readNext()) != null) {
                    System.out.println(nextLine[4]   "\n");
                    rows.add(nextLine[4]);
                    

                }

              
            } catch (IOException e) {
                e.printStackTrace();

            }

            for (int i = 0; i < rows.size(); i  ) {
                result[0] = rows.get(i);
            }

        }

    }
    System.out.println(result[0]   "\n");
    return result[0];
}

The console never write "System.out.println(result[0] "\n");" result[0] is affected inside the onlistener but I can't access it outside of it.

Thank you for your Help

CodePudding user response:

That is the expected behavior. The getFile API is an asynchronous operation, which means that it executes in the background while the rest of your code continues to run. Then when the operation is complete, your onSuccess is called with the result.

This is easiest to see if you add some logging:

Log.i("File", "1. Starting to load file");
gsReference.getFile(Objects.requireNonNull(localFile)).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
        Log.i("File", "2. Loaded file");
    }

}
Log.i("File", "3. Started to load file");

If you run this code it outputs:

  1. Starting to load file

  2. Started to load file

  3. Loaded file

This is probably not what you expected, but it is working by design - and it does completely explain why your System.out.println(result[0] "\n"); doesn't show the file contents: the file hasn't been loaded yet.

This is an incredibly common problem, as most I/O and network APIs are asynchronous these days. The solution is always the same: any code that needs the data that is asynchronously loaded has to be inside the onSuccess handler, be called from there, or otherwise synchronized.

This means for example that you can't return the value from the file, as the return runs before the load has completed, and you'll instead want to pass a callback to your readFromCsv function, very similar to the OnSuccessListener.

For more on this, I recommend reading:

  • Related