I need help with a flutter application linked with Firebase. This application has a login method and I want to have a picture where users can update it whenever they want.
For now, I manage to replace a picture who’s already existing in a Firebase Storage’s file by a picture taken from the gallery of a phone (uploadFile). Also I can take back this picture from Firebase Storage if it’s already existing in Firebase Storage (getProfilImage).
The issue:
However, when I want to add a new picture from my application to the Firebase Storage, Firebase doesn’t allow my user to create a new file with the new picture and my app crashed.
If someone could give me a help in order to change the picture of the user without already having a file for this picture in Firebase Storage, I would appreciate
The debug console error
E/StorageException(17322): StorageException has occurred.
E/StorageException(17322): Object does not exist at location.
E/StorageException(17322): Code: -13010 HttpResult: 404
E/StorageException(17322): { "error": { "code": 404, "message": "Not Found." }}
E/StorageException(17322): java.io.IOException: { "error": { "code": 404, "message": "Not Found." }}
The function to upload an image to Firebase Storage:
NB: The code works when $currentUser is replaced by an already existing file
Future uploadFile() async {
Reference storageRef = storage.ref().child('UsersImageProfil/$currentUser.png');
UploadTask uploadTask = storageRef.putFile(imageProfilFile!);
await uploadTask.whenComplete(() {
print('File uploaded');
setState(() {
imageProfilFile = null;
});
});
}
The function to get the image from Firebase Storage
NB: The code works when $currentUser is replaced by an already existing file
void initState() {
super.initState();
getProfilImage();
}
getProfilImage() {
Reference ref = storage.ref().child('UsersImageProfil/$currentUser.png');
ref.getDownloadURL().then((downloadUrl) {
setState(() {
userPhotoUrl = downloadUrl.toString();
});
}).catchError((e) {
setState(() {
userPhotoUrl = defaultImageUrl;
});
print('Une erreur est survenue: ${e.error}');
});
}
The function who display the picture
class SetPhotoProfilState extends State<SetPhotoProfil> {
File? imageProfilFile;
final picker = ImagePicker();
String? userPhotoUrl;
String defaultImageUrl = 'https://svgsilh.com/png-1024/2098873.png';
@override
Widget build(BuildContext context) {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(kColorPrimary)),
onPressed: () async {
Map<Permission, PermissionStatus> statuses = await [
Permission.storage,
Permission.camera,
].request();
if (statuses[Permission.storage]!.isGranted &&
statuses[Permission.camera]!.isGranted) {
showImagePicker(context);
} else {
print('No permission');
}
},
child: Text("Modifier sa photo de profil")),
userPhotoUrl == null
? CircleAvatar(
radius: 42,
backgroundColor: kColorPrimary,
child: CircleAvatar(
radius: 40,
backgroundImage: NetworkImage(
defaultImageUrl, // Remplacez l'URL par le lien de votre image de profil
),
),
)
: CircleAvatar(
radius: 42,
backgroundColor: kColorPrimary,
child: CircleAvatar(
radius: 40, backgroundImage: NetworkImage(userPhotoUrl!)),
),
],
));
}
The showImagePicker function
void showImagePicker(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (builder) {
return Card(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height / 5.2,
margin: const EdgeInsets.only(top: 8.0),
padding: const EdgeInsets.all(12),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: InkWell(
child: Column(
children: [
Icon(Icons.image, size: 60.0),
SizedBox(
height: 12.0,
),
Text(
'Gallerie',
textAlign: TextAlign.center,
)
],
),
onTap: () {
_imgFromGallery();
Navigator.pop(context);
},
),
),
_imgFromGallery() async {
await picker
.pickImage(source: ImageSource.gallery, imageQuality: 50)
.then((value) {
if (value != null) {
imageCache.clear();
setState(() {
imageProfilFile = File(croppedFile.path);
convertImageToPNG();
uploadFile();
});
}
});
}
Also I’ve already modify the Storage rules:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
2
Answers
I resolved my issue. It seems that the error came from the getProfilImage() function. There is the new getProfilImage() function :
I just had to put an if condition in order to help firebase storage to manage the case if there wasn't any picture yet in the storage.I also change the UploadFile function:
}
try updating yours with this rule