Search code examples
flutterfile-uploadserverconfiguration

How should I configure the hosting server to upload a file from Flutter application?


I want to create a file directory for my Flutter mobile application and upload files (any kind of images or pdf files).

I use the following code for selecting and uploading the file to the server :

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:file_picker/file_picker.dart';

class fileUpload extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: UploadScreen(),
    );
  }
}

class UploadScreen extends StatefulWidget {
  @override
  _UploadScreenState createState() => _UploadScreenState();
}

class _UploadScreenState extends State<UploadScreen> {
  File? _selectedFile;

  Future<void> _selectFile() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles();

    if (result != null) {
      setState(() {
        _selectedFile = File(result.files.single.path!);
      });
    }
  }

  Future<void> _uploadFile() async {
    if (_selectedFile == null) {
      print('no files picked');
      return;
    }

    var uri = Uri.parse('http://myhostingdomain.com/specialdirectory'); // Sunucunun URL'si

    var request = http.MultipartRequest('POST', uri);
    request.files.add(await http.MultipartFile.fromPath('file', _selectedFile!.path));

    var response = await request.send();
    if (response.statusCode == 200) {
      print('successfully uploaded.');
    } else {
      print('Error returned: ${response.reasonPhrase}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sample file upload page'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _selectFile,
              child: Text('Choose a file'),
            ),
            SizedBox(height: 20),
            _selectedFile != null
                ? Text('selected file: ${_selectedFile!.path}')
                : Text('no files found'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _uploadFile,
              child: Text('upload the file'),
            ),
          ],
        ),
      ),
    );
  }
}

When I run my mobile application everything looks file and file seems uploaded. But when I check the file server at the hosting destination, there is no file uploaded.

I believe I have to configure the public hosting server and send the authentication before I start the uploading the file.

How should I update my code to add the credentials while connecting the destination and additionally how should I configure the hosting server to accept uploadings?

Thank you

there are several solutions I found over internet but not including the credentials for a public hosting server.


Solution

  • Uploading a file is a multi-step process that requires work on the client and server side:

    Server Side:

    Create a folder to save your uploaded files. Make sure the folder is in your website directory and you can call it something like: UploadsFolder

    For this example, I am using localhost.

    Write the following code into a php file and call it uploadData.php

    <?php
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        try {
    
            // File handling
            $file = $_FILES['file'];
            $fileName = $file['name'];
            $fileTmpName = $file['tmp_name'];
            
    
            // Move the uploaded file to the desired directory
            $uploadsDirectory = 'UploadsFolder/';
            $targetPath = $uploadsDirectory . $fileName;
    
            move_uploaded_file($fileTmpName, $targetPath);
    
      
        } catch (Exception $e) {
            http_response_code(500); // Internal Server Error
        } 
    }
    ?>
    

    Client side:

    write the following commands in your terminal to install the http and file_picker packages in flutter:

    flutter pub add http
    flutter pub add file_picker

    Use the following code to upload your file

    import 'dart:io';
    import 'package:flutter/material.dart';
    import 'package:file_picker/file_picker.dart';
    import 'package:http/http.dart' as http;
    import 'package:http/http.dart';
    void main()=>runApp(const MyApp());
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: Scaffold(
            body: 
            Center(child:
            FileUploader()
          )),
        );
      }
    }
    // as widgets
    
    class FileUploader extends StatefulWidget {
      const FileUploader({super.key});
      @override
      State<FileUploader> createState() => _FileUploaderState();
    }
    
    class _FileUploaderState extends State<FileUploader> {
    String? fileName;
    PlatformFile? selectedFile;
    
    Future<void> _uploadFile() async {
        if (selectedFile == null) {
          print('no files picked');
          return;
        }
    
        var uri = Uri.parse('http://10.0.2.2/demoProject/uploadData.php'); // Sunucunun URL'si
    
        var request = http.MultipartRequest('POST', uri);
        request.files.add(await http.MultipartFile.fromPath('file', selectedFile!.path??""));
    
        var response = await request.send();
        if (response.statusCode == 200) {
          print('successfully uploaded.');
        } else {
          print('Error returned: ${response.reasonPhrase}');
        }
      }
    
    
    
    pickFile() async {
        FilePickerResult? result = await FilePicker.platform.pickFiles();
        if (result != null) {
          PlatformFile? file = result.files.first;
        setState(() {
          selectedFile=file;
          fileName=file.name;
    print("fileName is $fileName");
        });
        }
        return null;
      }  
      
      @override
      Widget build(BuildContext context) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
          
    ElevatedButton(onPressed: () async {
    await pickFile();
    
    
    }, child: const Text("Pick file to upload")),
    
    ElevatedButton(onPressed: ()async{
    if(selectedFile!=null){
        
    await _uploadFile();
    }
    }, child: const Text("Upload selected file"))
    
        ],);
      }
    }