king ramizy
king ramizy

Reputation: 25

Android Firebase download sound

I work on an Android application and I need to download some Sound from firebase storage, I get the sound name from the firebase realtime database.

My code :

public class DataSyncFb extends AsyncTask<Void, Integer, Void> {


private Context context;
private StorageReference mStorageRef;


public DataSyncFb(final Context context) {
    this.context = context;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
    Log.i("DataSincFB", "onPreExecute");
}


@Override
protected Void doInBackground(Void... voids) {
    final DatabaseHandler db = new DatabaseHandler(context);
    final FirebaseDatabase database = FirebaseDatabase.getInstance();

    DatabaseReference dbRef = database.getReference("categorie");
    dbRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            try {
                List<String> listCat = db.getAllCategoriesId();
                List<String> listSounds = db.getAllSoundsId();
                Log.i("test", String.valueOf(dataSnapshot.getValue()));
                Gson test = new Gson();

                JSONArray jsonArray = new JSONArray(test.toJson(dataSnapshot.getValue()));

                for (int i = 0; i < jsonArray.length(); i++){
                    JSONObject cat = jsonArray.getJSONObject(i);
                    String nom = cat.getString("nom");
                    String id = cat.getString("id");
                    if (!listCat.contains(id)) {
                        db.addCategorie(nom, id);
                    }

                    JSONArray sounds = cat.getJSONArray("son");
                    Log.i("cat", sounds.toString());
                    for (int j = 0; j < sounds.length(); j++){
                        JSONObject sound = sounds.getJSONObject(j);
                        String soundId = sound.getString("id");
                        if (!listSounds.contains(soundId)){

                            downloadSound();
                            db.addSound(soundId, sound.getString("nom"), sound.getString("lien") ,id);

                        }

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

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    Log.i("DataSyncFB", "onPostExecute");
}

private void downloadSound(){
    Log.v("download", "in function");

    try {
        StorageReference islandRef = FirebaseStorage.getInstance().getReferenceFromUrl("gs://soundbox-a6dd8.appspot.com").child("cjpcommodelouisxv.mp3");


        File localFile = null;

        localFile = File.createTempFile("cjpcommodelouisxv", "mp3");
        islandRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                Log.v("download", "Success");
                // Local temp file has been created
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception exception) {
                // Handle any errors
                Log.e("download", "Error");

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

I get this error :

E/StorageException: StorageException has occurred.                                                                              User does not have permission to access this object.                                                     Code: -13021 HttpResult: 403
E/firebase: ;local tem file not created  created com.google.firebase.storage.StorageException: User does not have permission to access this object.
E/StorageUtil: error getting token java.util.concurrent.ExecutionException: com.google.firebase.internal.api.FirebaseNoSignedInUserException: Please sign in before trying to get a token.
W/NetworkRequest: no auth token for request

I try to change the rules in Firebase > storage but nothing work.If you have any ideas to solve my problem. thank for your help.

Edit :

service firebase.storage {
 match /b/soundbox-a6dd8.appspot.com/o {
   match /{allPaths=**} {
     // Allow access by all users
     allow read, write: if true;
   }
 }
}

New error : E/firebase: ;local tem file created created /storage/emulated/0/cjpcommodelouisxv/cjpcommodelouisxv.mp3 E/StorageUtil: error getting token java.util.concurrent.ExecutionException: com.google.firebase.internal.api.FirebaseNoSignedInUserException: Please sign in before trying to get a token. W/NetworkRequest: no auth token for request

Upvotes: 1

Views: 3340

Answers (1)

Kushan
Kushan

Reputation: 5984

You storage security rules probably have an

allow write: if request.auth !=null

clause and here you don't seem to be using FirebaseAuth to authenticate the user.

For testing, is suggest you use signInAnonymously() method and sign the user transparently before writing to the storage.

FirebaseAuth mAuth = FirebaseAuth.getInstance(); 

Then in sign in before doing any of the stuff that you are doing

FirebaseUser user = mAuth.getCurrentUser();  
if (user != null) { 
     // do your stuff
} else { 
    signInAnonymously(); 
}

signInAnonymously() method is as follows

private void signInAnonymously(){ 
    mAuth.signInAnonymously().addOnSuccessListener(this, new OnSuccessListener<AuthResult>() {
        @Override public void onSuccess(AuthResult authResult) { 
             // do your stuff
         }
     }) .addOnFailureListener(this, new OnFailureListener() { 
            @Override public void onFailure(@NonNull Exception exception) { 
                  Log.e("TAG", "signInAnonymously:FAILURE", exception);
             }
     }); 
}

Also in the Firebase console, under authentication> signin methods, enable anonymous sign in

This may solve your problem

Alternatively if you don't want authentication for testing have the rules as:

allow write: if true;

DO THIS ONLY FOR TESTING AS THIS IS BASICALLY PUBLIC ACCESS

Then you can adjust your authentication approach according to your rules.

If your rules are not what i specified, please share your rules so that we can guide you accordingly rather than speculating and guessing

Upvotes: 3

Related Questions