Reputation: 25
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
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