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:
Starting to load file
Started to load file
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: