getDownloadUrl on Android returns me null

2

this time, I try to recover images that have been uploaded directly to Firebase Storage, a structure for the database has been generated in the following way:

DATABASE

{
  "categorias" : {
    "categoria1" : {
      "nombre" : "Licores",
      "ruta" : "categoria1.jpg"
    },
    "categoria2" : {
      "nombre" : "Bebidas no alcoholicas",
      "ruta" : "categoria2.jpg"
    }
  }
}

THE RULES OF ACCESS TO DATA

The rules that have been determined for accessing the data are the following:

{
  "rules": {
    "categorias":{
      ".read": "auth.uid != null",
      ".write": "auth.uid != null"      
    },
    "perfiles":{
      "$uid":{
        ".read": "auth.uid === $uid",
        ".write": "auth.uid === $uid"      
      }
    }      
  }
}

IN THE CODE

@Override
public void onBindViewHolder(@NonNull ViewHolderCategorias viewHolderCategorias, int position) {

    viewHolderCategorias.nombreCategoria.setText(listaCategorias.get(position).getNombre());

    rutaImagen = storageRef.child(listaCategorias.get(position).getRuta());
    rutaImagen.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
        @Override
        public void onSuccess(Uri uri) {
            myUrl = uri.toString();
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {

        }
    });

But despite having read the information that is in Android Developers and have taken the code that suggests there, because the getDownloadUrl returns null since it never enters to execute that portion of the code found in the onSuccess, what I intend is to send that url to Glide to show the image, since what I did before was directly send a StorageReference (pathImage) does not work for me because it returns the storage address (gs: //) and not the download address (https: //), then based on that storage address I intend to get to the download address. Any suggestions on how I can achieve it?

I would appreciate it in advance.

    
asked by Andrés Jara Avila 23.11.2018 в 17:15
source

1 answer

0

First save the link returned by Firebase Storage when uploading your file.

//Se parece a este :D
https://firebasestorage.googleapis.com/v0/b/software-25c1e.appspot.com/o/xxxx.docx?alt=media&token=155bf282-cdff-4693-9755-39cdb4232b65

Second, with the download url, you download in this way. You must request permission to use the Storage (WRITE_EXTERNAL_STORAGE)

In Java

    FirebaseStorage storage = FirebaseStorage.getInstance();
    StorageReference storageRef = storage.getReferenceFromUrl("URL ARCHIVO");
    //Nombre de la carpeta donde vas a guardar los archivos dentro de tu storage
    File rootPath = new File(Environment.getExternalStorageDirectory(), "Asesorias Ulima");
    if (!rootPath.exists()) {
        rootPath.mkdirs();
    }
    final File localFile = new File(rootPath, "NOMBRE_DEL_ARCHIVO.PNG");
    if (!localFile.exists()) {
        storageRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                openFile(localFile);
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();
            }
        });
    }

    //Funcion para poder abrir el archivo que haz descargado
    public void openFile(File url) {

        Uri uri = FileProvider.getUriForFile(this,
                BuildConfig.APPLICATION_ID + ".provider",
                url.getAbsoluteFile());

        Intent intent = new Intent(Intent.ACTION_VIEW);

        if (url.toString().contains(".doc") || url.toString().contains(".docx")) {
            // Word document
            intent.setDataAndType(uri, "application/msword");
        } else if (url.toString().contains(".pdf")) {
            // PDF file
            intent.setDataAndType(uri, "application/pdf");
        } else if (url.toString().contains(".ppt") || url.toString().contains(".pptx")) {
            // Powerpoint file
            intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
        } else if (url.toString().contains(".xls") || url.toString().contains(".xlsx")) {
            // Excel file
            intent.setDataAndType(uri, "application/vnd.ms-excel");
        } else if (url.toString().contains(".zip") || url.toString().contains(".rar")) {
            // WAV audio file
            intent.setDataAndType(uri, "application/x-wav");
        } else if (url.toString().contains(".rtf")) {
            // RTF file
            intent.setDataAndType(uri, "application/rtf");
        } else if (url.toString().contains(".wav") || url.toString().contains(".mp3")) {
            // WAV audio file
            intent.setDataAndType(uri, "audio/x-wav");
        } else if (url.toString().contains(".gif")) {
            // GIF file
            intent.setDataAndType(uri, "image/gif");
        } else if (url.toString().contains(".jpg") || url.toString().contains(".jpeg") || url.toString().contains(".png")) {
            // JPG file
            intent.setDataAndType(uri, "image/jpeg");
        } else if (url.toString().contains(".txt")) {
            // Text file
            intent.setDataAndType(uri, "text/plain");
        } else if (url.toString().contains(".3gp") || url.toString().contains(".mpg") || url.toString().contains(".mpeg") || url.toString().contains(".mpe") || url.toString().contains(".mp4") || url.toString().contains(".avi")) {
            // Video files
            intent.setDataAndType(uri, "video/*");
        } else {
            //if you want you can also define the intent type for any other file
            //additionally use else clause below, to manage other unknown extensions
            //in this case, Android will show all applications installed on the device
            //so you can choose which application to use
            intent.setDataAndType(uri, "*/*");
        }
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);

    }

In Kotlin

    val storage = FirebaseStorage.getInstance()
    val storageRef = storage.getReferenceFromUrl("URL DEL ARCHIVO")
    //Nombre de la carpeta donde vas a guardar los archivos dentro de tu storage
    val rootPath = File(Environment.getExternalStorageDirectory(), "Asesorias Ulima")
    if (!rootPath.exists()) {
        rootPath.mkdirs()
    }
    val localFile = File(rootPath, "NOMBRE_DEL_ARCHIVO.PNG")
    if (!localFile.exists()) {
        storageRef.getFile(localFile).addOnSuccessListener {
            openFile(localFile)
            //  updateDb(timestamp,localFile.toString(),position);
        }.addOnFailureListener { exception ->
            toast("local tem file not created  created \" + $exception")
        }
    }


//Funcion para poder abrir el archivo que haz descargado
fun openFile(url:File) {

    val uri = FileProvider.getUriForFile(this,
            BuildConfig.APPLICATION_ID + ".provider",
            url.absoluteFile)

    val intent = Intent(Intent.ACTION_VIEW)

    if (url.toString().contains(".doc") || url.toString().contains(".docx")) {
        // Word document
        intent.setDataAndType(uri, "application/msword")
    } else if (url.toString().contains(".pdf")) {
        // PDF file
        intent.setDataAndType(uri, "application/pdf")
    } else if (url.toString().contains(".ppt") || url.toString().contains(".pptx")) {
        // Powerpoint file
        intent.setDataAndType(uri, "application/vnd.ms-powerpoint")
    } else if (url.toString().contains(".xls") || url.toString().contains(".xlsx")) {
        // Excel file
        intent.setDataAndType(uri, "application/vnd.ms-excel")
    } else if (url.toString().contains(".zip") || url.toString().contains(".rar")) {
        // WAV audio file
        intent.setDataAndType(uri, "application/x-wav")
    } else if (url.toString().contains(".rtf")) {
        // RTF file
        intent.setDataAndType(uri, "application/rtf")
    } else if (url.toString().contains(".wav") || url.toString().contains(".mp3")) {
        // WAV audio file
        intent.setDataAndType(uri, "audio/x-wav")
    } else if (url.toString().contains(".gif")) {
        // GIF file
        intent.setDataAndType(uri, "image/gif")
    } else if (url.toString().contains(".jpg") || url.toString().contains(".jpeg") || url.toString().contains(".png")) {
        // JPG file
        intent.setDataAndType(uri, "image/jpeg")
    } else if (url.toString().contains(".txt")) {
        // Text file
        intent.setDataAndType(uri, "text/plain")
    } else if (url.toString().contains(".3gp") || url.toString().contains(".mpg") || url.toString().contains(".mpeg") || url.toString().contains(".mpe") || url.toString().contains(".mp4") || url.toString().contains(".avi")) {
        // Video files
        intent.setDataAndType(uri, "video/*")
    } else {
        //if you want you can also define the intent type for any other file
        //additionally use else clause below, to manage other unknown extensions
        //in this case, Android will show all applications installed on the device
        //so you can choose which application to use
        intent.setDataAndType(uri, "*/*")
    }
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    startActivity(intent)

}

Second in your manifest put the following.

//Para los permisos
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />


    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

Third creates the provider_paths file inside the xml folder within the res folder.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
    
answered by 23.11.2018 / 17:49
source