Getting 500 Internal Server Error when uploading image using Retrofit and Dio in Flutter

51 Views Asked by At

I'm facing an issue while trying to upload an image using Dio and Retrofit in my Flutter app. The strange part is that the API endpoint works correctly in Postman, but when I attempt to upload an image from my app, I receive a 500 Internal Server Error.

Here's a snippet of my Flutter code:

This is my api_service


import 'package:dio/dio.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:retrofit/http.dart';
import 'package:retrofit/retrofit.dart';
import 'package:tappbiz/network_manager/models/user_model.dart';

part 'api_service.g.dart';

@RestApi(baseUrl: "https://xxx.xxx..xxx/api/")
abstract class ApiService {
  factory ApiService(Dio dio, {String baseUrl}) = _ApiService;

  @POST("/sendOtp")
  Future<ApiResponse> sendOtp(@Body() Map<String, dynamic> data);



  @POST("/register")
  Future<TokenResponse> register(@Body() Map<String, String> body);

  @POST("/login")
  Future<TokenResponse> login(@Body() Map<String, String> body);

  @GET("/me")
  Future<ProfileMediaResponse> me(@Header('Authorization') String token);

  @POST("/profileMedia")
  @FormUrlEncoded()
  Future<ProfileMediaResponse> profileMedia(
      @Header('Authorization') String token,
      @Field('media') MultipartFile image);
}



And,this is my Image Upload code page:

class _ProfileMediaPageState extends State<ProfileMediaPage> {
  final ApiService apiService = ApiService(Dio());

  late File? _selectedImage = null;

  Future<void> _getImage(ImageSource source) async {
    final picker = ImagePicker();
    final pickedFile = await picker.pickImage(source: source);

    setState(() {
      _selectedImage = pickedFile != null ? File(pickedFile.path) : null;
    });
  }

  final ImagePicker _picker = ImagePicker();

  Future<File?> pickImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.gallery);
    if (pickedFile != null) {
      return File(pickedFile.path);
    }
    return null;
  }

  Future<MultipartFile> prepareImage(File imageFile) async {
    final imageBytes = await imageFile.readAsBytes();
    return MultipartFile.fromBytes(imageBytes,
        filename: imageFile.path.split('/').last);

    // ('media_${imageFile.path.split('/').last}', imageBytes);
  }

  Future<void> uploadPickedImage() async {
    String token = TokenManager.getInstance().authToken;
    final pickedImage = await pickImage();
    if (pickedImage != null) {
      final multipartImage = await prepareImage(pickedImage);
      final response =
          await apiService.profileMedia('Bearer $token', multipartImage);
      if (response.fullName!.isNotEmpty) {
        print("image upload successfully");
        // Image uploaded successfully
      } else {
        print("image not upload successfully");
        // Handle error
      }
    }
  }

  

  

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Stack(
              clipBehavior: Clip.none,
              children: [
                Container(
                  width: MediaQuery.of(context).size.width * 0.30,
                  height: MediaQuery.of(context).size.height * 0.15,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    color: Colors.grey[200], // Placeholder color
                  ),
                  child: _selectedImage != null
                      ? ClipOval(
                          child: Image.file(
                            _selectedImage!,
                            fit: BoxFit.cover,
                          ),
                        )
                      : const Icon(
                          Icons.person,
                          size: 50, // Adjust the size as needed
                        ),
                ),
                Positioned(
                  // bottom: 3,
                  top: MediaQuery.of(context).size.height * 0.1,
                  left: MediaQuery.of(context).size.width * 0.17,
                  child: Container(
                    height: 45,
                    width: 45,
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      border: Border.all(color: Colors.blue),
                      color: Colors.blue,
                    ),
                    child: IconButton(
                      color: Colors.white,
                      icon: const Center(child: Icon(Icons.camera_alt)),
                      onPressed: selectProfileImage,
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              // onPressed: _uploadImage,
              onPressed: uploadPickedImage,
              child: const Text('Upload'),
            ),
          ],
        ),
      ),
    );
  }
}

I've already tried my best, but I'm still encountering the 500 issue.

The API call seems to be working fine when tested with Postman, so I'm wondering if there's something specific to Dio or Retrofit that I might be missing.

0

There are 0 best solutions below