Ion-input type="file" full path


#1

Hello,

I want that my user can choose a file in his browser and then upload that file to firebase.
The filechooser plugin only works on Android.

I try


<ion-item>
      <ion-label id="profile_image" color="primary" stacked>Profilbild wählen</ion-label>
      <ion-input type="file" accept="image/*" id="upload" [(ngModel)]="imageFilePath" (ionChange)="imageFilePath_change($event)"></ion-input>
    </ion-item>

But in my imageFilePath is something like “C:\fakepath\filename.png”.

Google says that this is for security reasons. Is there any way to get the full path in an browser enviroment?


#2

What are you planning on using it for?


#3

Upload a user profile image to firebase and show it in the menu as avatar is my target.


#4

You have the file contents, presumably. I assume there is already some sort of name that would be being displayed alongside the avatar. I don’t see why the file path is of any necessity.


#5

IIRC that’s not allowed in Javascript specifically due to security concerns. The new-ish File API implemented in Firefox seems to have a mozFullPath, which looks like what you need. But even if it works, try not to use it (mozilla only and it’s not even documented what it’s for).


#7

I don’t understand this. You have the file contents, no? Isn’t that sufficient?


#8

@rapropos Ahh ok you mean I don’t need the file path.

I changed my Code this way:

HTML

    <ion-item>
      <ion-label id="profile_image" color="primary" stacked>Profilbild wählen</ion-label>
      <ion-input type="file" accept="image/*" (change)="changeListener($event)"></ion-input>
    </ion-item>

TS

 file: File;
 changeListener($event) : void {
    this.file = $event.target.files[0];
  }

  saveProfile_click() {
    console.log("saveProfile_click");
    // Add your code here
    this.afAuth.authState.take(1).subscribe(auth => {
      this.afDatabase.object(`profile/${this.uid}`).set(this.profile)
        .then(() => {
          this.uploadProfileImage();
          this.navCtrl.pop();
        });
    })
  }

  uploadProfileImage(){
    console.log("uploadProfileImage");
    let fileRef = firebase.storage().ref('profileImages/' + this.uid + ".jpg");
    fileRef.put(this.file).then(function(snapshot) {
      console.log('Uploaded a blob or file!');
    });
  }

And it works :slight_smile:


#9

hi there
i hope you would be fine.
it would very kind of you if i can get some guidance from you on this

  <ion-item>
    <ion-label id="profile_image" color="primary" stacked>Profilbild wählen</ion-label>
    <ion-input type="file" accept="image/*" (change)="changeListener($event)"></ion-input>
  </ion-item>
changeListener($event) : void {
     this.file = $event.target.files[0];
     console.log(this.file);
   }

I’m new to ionic. on this code I’m getting the image Data (file). i need the path of the image so i can convert it to Base64 and send it to API


#10

If I remember right, to get the path is not possible for security reasons. The browser wont allow you to interact with the filesystem directly.

I send the file as form data to the server and save it there. Storing the filename in the user profile at my database. I’m also do some stuff like resizing on the server side.

When I need the image in my app I have a route on my server that gets the profile id and send the image as base64 string back to my app.


#11

so how how can i upload it to server throught api

Do input file type work for both ios and android


#12

Yes it works everywhere :slight_smile:

This is my function on the client side. You can extract the important part:


async uploadAvatar(token: string, avatar: File): Promise<Profile> {
    try {
      let formData = new FormData();
      formData.append('avatar', avatar, avatar.name);
      this.userProfile = await this.httpClient.post<Profile>(
        `${this.server}${this.profilesAvatarsRoute}`, 
        formData, 
        {}).toPromise();
      if (this.userProfile.avatar) {
        this.userProfile.avatar = await this.getUserAvatarBase64(token);
      }
      return this.userProfile;
    } catch (err) {
      throw new Error(err.status + " - " + err.statusText);
    }
  }

This is my code on the server side:

app.post('/profiles/avatars', authenticate, uploadProfileAvatar.single('avatar'), function (req, res, next) {
    let fileName = req.user._id.toString() + path.extname(req.file.originalname);
    let filePath = path.join(__dirname, './private/images/avatars/profiles', fileName);
    if (fs.existsSync(filePath)) {
        jimp.read(filePath, function (err, image) {
            if (err) throw err;
            image.resize(256, 256)            // resize
                .quality(60)                 // set JPEG quality
                .write(filePath);            // save
        });
        ...
})

and the middleware

const uploadProfileAvatar = multer({
    storage: profilesStorage,
    fileFilter: function (req, file, callback) {
        var ext = path.extname(file.originalname);
        if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
            return callback(new Error('Only images are allowed'))
        }
        callback(null, true)
    },
    limits: {
        fileSize: 1024 * 1024 * 10 // images up to 10MB
    }
});