Can't add image to existing entry - Strapi v4

I was able to create a solution for my desired use being:

User can upload a new profile picture to replace their old one.

Please note I am using the S3 Upload Provider. I know this code may not be super intuitive but it works.

strapi-server.js

plugin.controllers.user.updateProfilePicture = async (ctx) => {
    const user = ctx.state.user;
    

    AWS.config.update({ accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_KEY });


    // User has to be logged in to update themselves
    if (!user) {
      return ctx.unauthorized();
    }

    //Check for existing profile picture
    const userData = await strapi.query('plugin::users-permissions.user').findOne({
      where: { id: user.id },
      populate: { 'profilePicture': true }
    });

    //Get file from request
    const newPic = ctx.request.files.file

    if (userData.profilePicture != null) {
      //Delete existing profile picture
      const s3 = new AWS.S3()
      const params = {
        Bucket: process.env.AWS_BUCKET,
        Key: userData.profilePicture.url.split('/').pop(),
      }
      await s3.deleteObject(params).promise()

      //Delete existing profile picture from entity
      await strapi.query('plugin::users-permissions.user').update({
        where: {id: user.id},
        data:{
          profilePicture: null
        }
      });

      //Call upload function to upload new profile picture
      await strapi.plugin("upload").services.upload.upload({
        data: {
          ref: "plugin::users-permissions.user",
          refId: user.id,
          field: 'profilePicture',
          source: "users-permissions"
        },
        files: {
          path: newPic.path,
          name: newPic.name,
          type: newPic.type,
          size: newPic.size
        }
      })

      return ctx.body = {
        message: "Profile picture updated"
      }

    } else {
      //Call upload function to upload new profile picture
      await strapi.plugin("upload").services.upload.upload({
        data: {
          ref: "plugin::users-permissions.user",
          refId: user.id,
          field: 'profilePicture',
          source: "users-permissions"
        },
        files: {
          path: newPic.path,
          name: newPic.name,
          type: newPic.type,
          size: newPic.size
        }
      })

      return ctx.body = {
        message: "Profile picture updated"
      }
    }
  }

Im sure the same logic can be applied with other upload providers, let me know if you anyone has any questions or suggestions to improve this snippet.

4 Likes