Nos utilisateurs peuvent dorénavant récupérer une image enregistrée sur leur téléphone depuis notre mini-application Android FirebaseOC ! Bon en revanche, ils ne peuvent toujours pas l'envoyer dans un message sur le chat.
Remédions à ce problème immédiatement !
Envoyez une image sur Firebase Storage
Afin d'envoyer une image sur Firebase, il nous faudra dans un premier temps installer le module "storage" de la librairie FirebaseUI. Pour cela, ajoutez à votre fichier build.gradle la ligne suivante.
Extrait du fichier build.gradle :
dependencies {
...
implementation 'com.firebaseui:firebase-ui-storage:7.1.1'
}
Ce module nous permettra d'envoyer très facilement des images sur Firebase. Avant de réaliser cette fonctionnalité, nous allons d'abord créer une requête sur le Firestore permettant de créer un nouveau message contenant une image...
Mais comment intégrer une image dans un objet Message ? Cela me semble impossible !
Nous n'avons pas besoin d'ajouter l'image entière dans un objet Message, mais plutôt son URL.
Nous enverrons dans un premier temps notre image sur l'espace de stockage Firebase Storage, qui nous renverra l'URL générée de cette image fraîchement créée, pour ensuite que nous puissions créer l'objet Message avec cette URL.
Extrait de ChatRepository :
public final class ChatRepository {
...
public void createMessageWithImageForChat(String urlImage, String textMessage, String chat){
userManager.getUserData().addOnSuccessListener(user -> {
// Creating Message with the URL image
Message message = new Message(textMessage, urlImage, user);
// Storing Message on Firestore
this.getChatCollection()
.document(chat)
.collection(MESSAGE_COLLECTION)
.add(message);
});
}
}
Explications : Rien de bien compliqué ici, nous implémentons simplement une méthode nous permettant de créer un objet Message contenant l'URL d'une image précédemment envoyée, puis nous sauvegardons ce Message dans Firestore.
Du coup, je ne peux pas envoyer ce message tant que je n'ai pas l'URL d'une image ?
Eh oui ! Comme vous l'aurez compris, cette méthode sera appelée après que avoir envoyé avec succès notre image sur Firebase.
Extrait de ChatRepository :
public final class ChatRepository {
...
public UploadTask uploadImage(Uri imageUri, String chat){
String uuid = UUID.randomUUID().toString(); // GENERATE UNIQUE STRING
StorageReference mImageRef = FirebaseStorage.getInstance().getReference(chat + "/" + uuid);
return mImageRef.putFile(imageUri);
}
...
}
Explications : Cette méthode nous permettra de créer une référence vers l'espace de stockage de Firebase (FirebaseStorage.getInstance().getReference(uuid)
), afin d'y envoyer par la suite notre image (via son URI) grâce à la méthode putFile()
.
Extrait de ChatManager :
public class ChatManager {
...
public void sendMessageWithImageForChat(String message, Uri imageUri, String chat){
chatRepository.uploadImage(imageUri, chat).addOnSuccessListener(taskSnapshot -> {
taskSnapshot.getStorage().getDownloadUrl().addOnSuccessListener(uri -> {
chatRepository.createMessageWithImageForChat(uri.toString(), message, chat);
});
});
}
}
Explications : Nous avons créé une fonction uploadImage()
qui se charge d'uploader l'image sur Storage et nous retourne une UploadTask.
Nous utilisons cette fonction dans notre manager, dans la fonction sendMessageWithImageForChat()
afin de sauvegarder notre image. Lors du succès de la sauvegarde (dans le callback créé avec la fonction addOnSuccessListener()
) nous créons ensuite le message avec l'url que l'on récupère du callback.
Une fois l'image correctement envoyée et enregistrée, l'URL correspondante de cette nouvelle ressource créée nous est renvoyée par Firebase. Nous la récupérons pour ensuite créer et sauvegarder notre objet Message sur le Firestore.
Nous allons ensuite modifier notre MentorChatActivity en conséquence.
Extrait de MentorChatActivity :
public class MentorChatActivity extends BaseActivity<ActivityMentorChatBinding> implements MentorChatAdapter.Listener {
...
private void sendMessage(){
// Check if user can send a message (Text not null + user logged)
boolean canSendMessage = !TextUtils.isEmpty(binding.chatEditText.getText()) && userManager.isCurrentUserLogged();
if (canSendMessage){
String messageText = binding.chatEditText.getText().toString();
// Check if there is an image to add with the message
if(binding.imagePreview.getDrawable() == null){
// Create a new message for the chat
chatManager.createMessageForChat(messageText, this.currentChatName);
}else {
// Create a new message with an image for the chat
chatManager.sendMessageWithImageForChat(messageText, this.uriImageSelected, this.currentChatName);
binding.imagePreview.setImageDrawable(null);
}
// Reset text field
binding.chatEditText.setText("");
}
}
...
}
Explications : Nous avons uniquement modifié notre fonction sendMessage() qui sera appelée quand l'utilisateur appuiera sur le bouton "Envoyer" afin de vérifier s'il y a une image dans la preview. Si c'est le cas, nous appelons la fonction adéquate du manager sendMessageWithImageForChat()
.
Et c'est tout !
Lancez votre application, et essayez d'envoyer un message contenant une image. Une fois le message et son image envoyés, vous devriez voir apparaître cette dernière depuis l'interface Web de Firebase.
En résumé
Vous pouvez stocker tout type de fichier au sein de Firebase Storage.
Le moyen le plus simple de récupérer ces fichiers est d'accéder à leurs urls.