i am actually working on a mobile app in ionic v3 with angular5
The goal is to be able to take a picture or choose from existing ones and then upload it to the server. The first part is done, but i am struggling with the upload.
The api needs multipart/form-data which must consist of two requests. First with text part and second is the image.
Is there any solution for this?
This is what I have done for similar requirement
takePhoto() {
this.camera.getPicture({
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.CAMERA,
encodingType: this.camera.EncodingType.PNG,
saveToPhotoAlbum: true
}).then(imageData => {
this.myPhoto = imageData;
this.uploadPhoto(imageData);
}, error => {
this.functions.showAlert("Error", JSON.stringify(error));
});
}
selectPhoto(): void {
this.camera.getPicture({
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
destinationType: this.camera.DestinationType.FILE_URI,
quality: 100,
encodingType: this.camera.EncodingType.PNG,
}).then(imageData => {
this.myPhoto = imageData;
this.uploadPhoto(imageData);
}, error => {
this.functions.showAlert("Error", JSON.stringify(error));
});
}
private uploadPhoto(imageFileUri: any): void {
this.file.resolveLocalFilesystemUrl(imageFileUri)
.then(entry => (<FileEntry>entry).file(file => this.readFile(file)))
.catch(err => console.log(err));
}
private readFile(file: any) {
const reader = new FileReader();
reader.onloadend = () => {
const formData = new FormData();
const imgBlob = new Blob([reader.result], { type: file.type });
formData.append('evaluationID', this.currentEvaluation.evaluationId);
formData.append('standardID', this.currentEvaluation.id);
formData.append('score', this.currentEvaluation.score);
formData.append('comment', this.currentEvaluation.comment);
formData.append('file', imgBlob, file.name);
this.saveStandard(formData);
};
reader.readAsArrayBuffer(file);
}
And here is code for provider
saveStandard(receivedStandardInfo:any){
return new Promise((resolve, reject) => {
this.http.post(apiSaveStandard,receivedStandardInfo)
.subscribe(res => {
resolve(res);
}, (err) => {
console.log(err);
reject(err);
});
}).catch(error => { console.log('caught', error.message); });
}
Related
I'm trying to login users with Facebook and Firebase, I have followed the documentation and some tutorials but I cannot make it work. I'm having this:
enter image description here
Plugin version:
"cordova-plugin-facebook4": "^6.4.0",
Also:
"cordova-plugin-facebook4": {
"APP_ID": "47**********",
"APP_NAME": "Mimas"
},**
My code:
public authWithFacebook(): Promise<any> {
return new Promise(async (resolve, reject) => {
if (this.platform.is('cordova')) {
await this.facebook.login(['public_profile']).then((res) => {
console.log(res);
const credential = firebase.auth.FacebookAuthProvider.credential(res.authResponse.accessToken);
this.afAuth.auth.signInWithCredential(credential).then(response => {
console.log(response);
resolve(response);
}).catch(err => {
console.log(err);
reject(this.translate.get(err.code));
});
}).catch(err => {
console.log("ERROR =========>");
console.log(err);
reject();
});
} else {
console.log("ELSEEEEEE =========>");
const fbprovider = new firebase.auth.FacebookAuthProvider();
this.afAuth.auth.signInWithPopup(fbprovider).then(res => {
resolve(res);
}).catch((e) => {
reject(e);
});
}
});
}
I've been working on getting a custom tab working in MS teams using MSAL. I've been following the example here: https://github.com/nmetulev/teams-msal and I can generate a token. I then try to forward this token to my API, where I build a security claim and call SignInAsync() to persist the cookie.
This then gets stored, and I forward to my standard page, but this does not page auth (I get unauthorized). Is there something I'm missing that I need to be doing?
Auth Page
const signIn = () => {
msalApp.acquireTokenRedirect(authenticationParameters);
}
const handleSignedIn = () => {
microsoftTeams.initialize();
microsoftTeams.authentication.notifySuccess();
}
const handleSignedOut = (error) => {
microsoftTeams.initialize();
microsoftTeams.authentication.notifyFailure(error);
}
const handleErrorReceived = (authError, accountState) => {
console.log(authError, accountState);
handleSignedOut({authError});
}
const handleTokenReceived = (response) => {
console.log(response);
handleSignedIn();
}
// MAIN
const msalApp = new Msal.UserAgentApplication(msalConfig);
msalApp.handleRedirectCallback((response) => handleTokenReceived(response), (error, state) => handleErrorReceived(error, state));
microsoftTeams.initialize();
microsoftTeams.getContext((context) => {
authenticationParameters = {
scopes: scopes,
loginHint: context.loginHint
};
setTimeout(() => {
attemptSilentSignIn().then(success => {
if (success) {
handleSignedIn();
} else {
signIn();
}
});
},
4000);
});
Sign In Page:
const attemptSilentSignIn = () => {
renderLoading();
if (msalApp.getAccount()) {
msalApp.acquireTokenSilent({ scopes }).then((response) => {
if (response && response.accessToken) {
handleSignedIn(response.accessToken);
} else {
handleSignedOut();
}
}, () => {
handleSignedOut();
})
} else {
handleSignedOut();
}
}
const signIn = () => {
renderLoading();
microsoftTeams.initialize(() => {
microsoftTeams.authentication.authenticate({
url: window.location.origin + "/resources/TeamsAuthFlow.html",
successCallback: () => attemptSilentSignIn(),
failureCallback: (error) => renderError(error)
});
});
}
const handleSignedIn = (accessToken) => {
microsoftTeams.initialize();
microsoftTeams.getContext((context) => {
var tenant = $("<input>").attr("id", "TenantId").attr("name", "TenantId").val(context.tid);
var token = $("<input>").attr("id", "AuthToken").attr("name", "AuthToken").val(accessToken);
var form = $("<form>").css("display", "none").attr("id", "target").attr("method", "POST").attr("action", "/api/TeamsTabSignIn").append(tenant).append(token).submit();
$("body").append(form);
$("#target").submit();
});
}
const handleSignedOut = () => {
renderSignedOutView();
}
// MAIN
let app = document.querySelector('.app');
const msalApp = new Msal.UserAgentApplication(msalConfig);
attemptSilentSignIn();
let authenticationParameters = null;
const handleErrorReceived = (authError, accountState) => {
console.log(authError, accountState);
handleSignedOut({ authError });
}
const handleTokenReceived = (response) => {
console.log(response);
handleSignedIn();
}
API Call
TenantId = Context.Request.Form["TenantId"];
AuthToken = Context.Request.Form["AuthToken"];
var principal = await _authHelper.SetPlatformUser(TenantId, AuthToken);
if (principal is ClaimsPrincipal cp)
{
await Context.SignInAsync("Cookies", cp, new AuthenticationProperties { IsPersistent = true });
Response.Redirect("/app/teamspage/Ticket");
}
(I've got say it in advance, sorry for my bad english) below is my typescript code in which is working perfectly. The takephoto method opens the device gallary and let the user choose one of pictures stored in the device and the uploadFile method tranfers the data image to the restfull api that I'm developing in asp.net core :
export class SelecionarAvatarPage {
imgrc:any ='assets/imgs/blank-profile-picture-973460_640-300x300.png';
imgurl: any =' ';
imgname: string;
constructor(public navCtrl: NavController, private transfer: FileTransfer, public loadingCtrl: LoadingController, private camera: Camera, public navParams: NavParams, private platform: Platform, public toastCtrl: ToastController) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad SelecionarAvatarPage');
}
takePhoto(sourceType:number) {
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true,
sourceType:sourceType,
}
this.camera.getPicture(options).then((imageData) => {
this.imgname = imageData;
let base64Image = 'data:image/jpeg;base64,' + imageData;
this.imgrc = base64Image;
this.imgurl = imageData;
}, (err) => {
// Handle error
});
}
presentToast(msg) {
let toast = this.toastCtrl.create({
message: msg,
duration: 3000,
position: 'bottom'
});
toast.onDidDismiss(() => {
console.log('Dismissed toast');
});
toast.present();
}
uploadFile() {
let loader = this.loadingCtrl.create({
content: "Uploading..."
});
loader.present();
const fileTransfer: FileTransferObject = this.transfer.create();
loader.dismiss();
let options: FileUploadOptions = {
fileKey: 'ionicfile',
fileName: 'ionicfile',
chunkedMode: false,
mimeType: "image/jpeg",
headers: {}
}
fileTransfer.upload(this.imgurl, 'http://192.168.0.000:5000/api/image', options)
.then((data) => {
console.log(data);
this.presentToast("Imagem foi enviada");
}, (err) => {
console.log(err);
loader.dismiss();
});
}
I want to know how I could upload image sent from an ionic app by File Transfer plugin in ASP.NET Core
Code for Upload: `
postFile(imageData,id) {
this.commonService.showLoader("Uploading........");
let currentName = imageData.substr(imageData.lastIndexOf('/') + 1);
let correctPath = imageData.substr(0, imageData.lastIndexOf('/') + 1);
let base64Image = imageData;
this.filePath.resolveNativePath(imageData)
.then(filePath =>base64Image)
.catch(err => console.log(err));
console.log(base64Image);
const fileTransfer = this.transfer.create();
let imageName = base64Image;
var options: FileUploadOptions = {
fileKey: "file",
fileName: imageName.substr(imageName.lastIndexOf('/') + 1),
mimeType: "image/png/jpeg",
chunkedMode: false,
params:{'Id': id},
headers: { 'Authorization':'Bearer '+ sessionStorage.getItem("token") }
}
return new Promise((resolve, reject) => {
fileTransfer.upload(imageName,encodeURI( this.MainURL + "/UploadMedia"), options)
.then((data) => {
console.log(data);
resolve(200);
}, (err) => {
this.commonService.hideLoader();
reject(500);
})
})
}
Code for Getting Image :private OpenCamera(): void {
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true,
sourceType: this.camera.PictureSourceType.CAMERA,
saveToPhotoAlbum: true
}
this.camera.getPicture(options).then((imageData) => {
// let base64Image = 'data:image/jpeg;base64,' + imageData;
let s = imageData;
this.AddIssueObj.file.push(s);
this.uploadcount = this.AddIssueObj.file.length;
}, (err) => {
// Handle error
});
}
Use destinationType: this.camera.DestinationType.DATA_URI, Becasue URL wont help you to send data to server but URI does. Plugins u need to use.import { FileUploadOptions } from '#ionic-native/file-transfer';
import { File } from '#ionic-native/file';`
I got it, I solved this problem by replacing the destination type to this.camera.DestinationType.FILE_URI instead of this.camera.DestinationType.DATA_URL
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true,
sourceType:sourceType,
}
I think my solution is in this question but I can't get it to work Promise.all behavior with RxJS Observables?
I'm trying to return an observable on two promises via forkJoin.
One promise gets an ID from the server and another processes a file to generate a thumbnail.
export function createSceneFromFile(action$) {
return action$.ofType(CREATE_SCENE_FROM_FILE)
.mergeMap(({locationId,file}) =>
createSceneThumb(locationId,file)
.map((res,preview) => {
console.log(res,preview)
if (res.error) {
return { type: CREATE_SCENE_FAILED, payload: res.message }
} else {
return {type: CREATE_SCENE_SUCCESS, payload: {...res.payload,preview} }
}
})
.catch(err => { return { type: CREATE_SCENE_FAILED, message: err } })
)
}
function createSceneThumb(locationId,file){
const request = fetch(`${API_URL}/location/${locationId}/createscene/${file.name}/`, {
method: 'get',
credentials: 'include',
}).then(res => res.json())
const thumb = fileToScenePreview(file)
return Observable.forkJoin(request,thumb)
}
export function fileToScenePreview(file){
return new Promise((resolve,reject)=>{
getFileThumb(file).then((canvas)=> {
canvas.toBlob((blob) => {
blob.lastModifiedDate = new Date()
blob.name = 'scenepreview_' + file.name + '.png'
const uploader = new S3Upload({
getSignedUrl: getSignedUrl,
uploadRequestHeaders: {'x-amz-acl': 'public-read'},
contentType: 'image/png',
scrubFilename: (filename) => filename.replace(/[^\w\d_\-.]+/ig, ''),
contentDisposition: 'auto',
s3path: 'assets/',
onError:()=>reject,
onFinishS3Put: ()=>resolve(blob.name),
})
uploader.uploadFile(blob)
})
})
})
}
But i never get a response.
Is this the right way of going about it?
I could register user(not admin), login, and store data in local.
But my program doesn't sync data to ROS2.
As far as I see document, maybe using Realm.Sync.addListener with admin.
I think admin user can access all object data. is wrong?
const addListener = (user) => new Promise((resolve, reject) => {
Realm.Sync.addListener('realm://usme-ros.usme.local:9080', user, '.*', 'change', (back) => {
console.log(back);
});
});
const registerUser = () => new Promise((resolve, reject) => {
Realm.Sync.User.register(URL, username, password, (err, res) => {
if (err) {
return reject(err);
}
console.log('finish register');
resolve();
})
});
const login = () => new Promise((resolve, reject) => {
Realm.Sync.User.login(URL, username, password, (err, user) => {
if (err) {
return reject(err);
}
resolve(user);
})
});
const registerVisit = (token) => new Promise((resolve, reject) => {
const visitSchema = {
name: 'Visit',
properties: {
id: 'int',
oneday_id: 'string',
arrival_date: 'string',
departure_date: 'string',
latitude: 'double',
longitude: 'double',
is_hidden: 'bool',
}
};
Realm.openAsync({ schema: [visitSchema] }, (err, realm) => {
if (err) {
return reject(err);
}
realm.write(() => {
realm.create('Visit', {
id: 1,
oneday_id: "ABCD-EFGH-IJKL-MNOP-QRST",
arrival_date: "2017-11-05 11:11:11",
departure_date: "2017-11-05 22:22:22",
latitude: 23.1234567,
longitude: 12.34567,
is_hidden: false,
});
});
resolve();
});
});
login()
.then((user) => addListener(user)
.then(() => registerVisit())
.catch(err => console.log(err)));