1

I am developing flutter app using riverpod as state management and laravel framework for backend. Currently i am working on implementing logic for saving user profile picture by selecting it with Image Picker package and sending it to the backend where it is stored in the files and the url path to that image is stored in the table AccountPicture that has fields id, url, color, user_id. Currently i managed to implement the saving of the image part but in the request where i save the image i also want to return it back to the flutter app in order to use it and here i am facing issue - once the request arives it has this form: Request Image

and i don't seem to know how to handle it. Here is the flutter service method making the api call:

Future<ProfilePicModel> testUploadAccountPic(XFile image, int id) async {
    try {
      final imageName = image.path.split('/').last;
      final formData = FormData.fromMap({
        'user_id':id,
        'image':await MultipartFile.fromFile(image.path, filename: imageName),
      });
      final request = await DioInstance().dio.post(ApiConfig.testUploadPic, data: formData);

      if(request.statusCode != null) {
        if(request.statusCode! >= 200 && request.statusCode! < 300) {
          final XFile image = request.data['image'];
          final color = request.data['color'];
          final profilePic = ProfilePicModel(image: image, color: color);
          return profilePic;
        }
      }
      throw "Unknown Error";
    } on DioError {
      throw "Server Error";
    } catch(e) {
      throw "Unknown Error";
    }
  }

Here is the dio interceptor headers that i am using:

@override
  Future<void> onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
    final user = SharedPreferencesService().getUser();
    if(user.accessToken.isNotEmpty && user != User(id: null, name: "", email: "", userType: 0, accessToken: "")){
      options.headers['accept'] = 'application/json';
      options.headers['content-type'] = 'multipart/form-data';
      options.headers['authorization'] = "Bearer ${user.accessToken}";
      super.onRequest(options, handler);
    }else {
      handler.reject(
        DioError(
          requestOptions: options,
          error: "Unauthorized User",
          response: Response(
            statusCode: 401,
            requestOptions: options,
          ),
        ),
      );
    }
  }

Here is the laravel method in the controller:

public function testUploadPic(Request $req)
    {
        $validator = Validator::make($req->all(),[
            'user_id' => 'required|integer',
            'image' => 'required|image|mimes:jpg,png,jpeg,gif,svg'
        ]);

        if($validator->fails()){
            return response()->json([
                'message'=>'Failed validator.'
            ], 422);
        }

        if ($req->hasFile('image')) {
            $user_id = $req->user_id;
            $imageFile = $req->file('image');
            $imageName = $imageFile->getClientOriginalName();
    
            // Store the image in storage
            $imagePath = Storage::putFileAs('profile_pics', $imageFile, $imageName);
    
            // Update the profile picture in the database
            $profilePic = AccountPicture::where('user_id', $user_id)->first();
    
            if (!$profilePic) {
                // Create a new profile picture if none exists for the user
                $profilePic = new AccountPicture();
                $profilePic->user_id = $user_id;
            }
    
            $profilePic->url = $imagePath;
            $profilePic->color = '';
            $profilePic->save();

            $file = Storage::get($profilePic->url);

            return response()->json([
                'image' => base64_encode($file),
                'color' => $profilePic->color,
            ]);
        }
    
        return response()->json([
            'message' => 'Profile picture upload failed',
        ], 400);
    }

and the route declared in api.php:

Route::post('/test_upload', [AccountController::class, 'testUploadPic']);

I tried looking for examples online on downloading saved image using flutter and laravel but could only find uploading and not getting back the picture. I've been banging my head over this for two days already. I also tried getting just the file like that:

public function getProfilePic(Request $req)
    {
        $validator = Validator::make($req->all(),[
            'user_id' => 'required|integer',
        ]);

        if($validator->fails()){
            return response()->json([
                'message'=>'Failed validator.'
            ], 422);
        }

        $user_id = $req->user_id;
        $picture = AccountPicture::where('user_id', $user_id)->first();
        $url = $picture->url;
        $file = file(storage_path('app/'.$url));

        return response()->$file;
    }

Route::post('/get_profile_pic', [AccountController::class, "getProfilePic"]);

Future<XFile> getProfilePic(int id) async {
    try {
      final formData = FormData.fromMap({
        'user_id':id,
      });
      final request = await DioInstance().dio.post(ApiConfig.getProfilePic, data: formData);

      if(request.statusCode != null) {
        if(request.statusCode! >= 200 && request.statusCode! < 300) {
          return request.data;
        }
      }
      throw "Unknown Error";
    } on DioError {
      throw "Server Error";
    } catch(e) {
      throw "Unknown Error";
    }
  }

but i was getting this error: Description on request from trying to get image directly

But if i try to get the image with get request directly like that:

public function testGetImage()
    {
        return response()->file(storage_path('app/profile_pics/download.jpg'));
    }

it doesn't give me backend errors but it does give me error while trying to assign the request.data to XFile variable: Error from request.data to XFile

But even though i am getting the image with GET request i need to do it with POST in order to send the user_id. If anyone can help i would be very grateful.

0 Answers0