Trying take a picture and upload it to firebase storage.
Here is my code;
import { Camera, CameraOptions } from '#ionic-native/camera';
async takePhoto() {
try{
const options: CameraOptions = {
quality: 50,
targetHeight: 600,
targetWidth: 600,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
const result = await this.camera.getPicture(options);
const image= `data:image/jpeg;based64,${result}`;
const pictures=storage().ref(`ProfilePictures/${this.myUid}`);
pictures.putString(image, `data_url`);
}
catch(e) {
console.error(e);
}
}
But it uploads a file that is not image actually. And it uploads a corrupted file even if I download it, I can't open it because its not an image.
Here is my firebase storage
thanks for reading please assist me
This may not be your problem as it's hard to say what the specific issue is but I've had similar issues in the past with image uploads, try this:
let result = await this.camera.getPicture(options);
result = result.replace(/(\r\n|\n|\r)/gm,"");
const image= `data:image/jpeg;based64,${result}`;
.replace(/(\r\n|\n|\r)/gm,"") removes all the newlines from the returned data.
Hope this helps.
takePhoto() {
const options: CameraOptions = {
quality: 50,
targetHeight: 600,
targetWidth: 600,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
let base64Image = 'data:image/jpeg;base64,' + imageData;
const pictures=storage().ref(`ProfilePictures/${this.myUid}`);
pictures.putString(base64Image, `data_url`);
}, (err) => {
}).present();
});
}
thats the way i solved the problem
Related
I'm using strapi 4 with nextjs.
In the app strapi holds music events for each user and each user should be able add and retrieve there own music events.
I am having trouble retrieving
each users music events from strapi 4
I have a custom route and custom controller
The custom route is in a file called custom-event.js and works ok it is as follows:
module.exports = {
routes: [
{
method: 'GET',
path: '/events/me',
handler: 'custom-controller.me',
config: {
me: {
auth: true,
policies: [],
middlewares: [],
}
}
},
],
}
The controller id a file called custom-controller.js and is as follows:
module.exports = createCoreController(modelUid, ({strapi }) => ({
async me(ctx) {
try {
const user = ctx.state.user;
if (!user) {
return ctx.badRequest(null, [
{messages: [{ id: 'No authorization header was found'}]}
])
}
// The line below works ok
console.log('user', user);
// The problem seems to be the line below
const data = await strapi.services.events.find({ user: user.id})
// This line does not show at all
console.log('data', data);
if (!data) {
return ctx.notFound()
}
return sanitizeEntity(data, { model: strapi.models.events })
} catch(err) {
ctx.body = err
}
}
}))
Note there are two console.logs the first console.log works it outputs the user info
The second console.log outputs the data it does not show at all. The result I get back
using insomnia is a 200 status and an empty object {}
The following line in the custom-controller.js seems to be where the problem lies it works for strapi 3 but does not seem to work for strapi 4
const data = await strapi.services.events.find({ user: user.id})
After struggling for long time, days infact, I eventually got it working. Below is the code I came up with. I found I needed two queries to the database, because I could not get the events to populate the images with one query. So I got the event ids and then used the event ids in a events query to get the events and images.
Heres the code below:
const utils = require('#strapi/utils')
const { sanitize } = utils
const { createCoreController } = require("#strapi/strapi").factories;
const modelUid = "api::event.event"
module.exports = createCoreController(modelUid, ({strapi }) => ({
async me(ctx) {
try {
const user = ctx.state.user;
if (!user) {
return ctx.badRequest(null, [
{messages: [{ id: 'No authorization header was found'}]}
])
}
// Get event ids
const events = await strapi
.db
.query('plugin::users-permissions.user')
.findMany({
where: {
id: user.id
},
populate: {
events: { select: 'id'}
}
})
if (!events) {
return ctx.notFound()
}
// Get the events into a format for the query
const newEvents = events[0].events.map(evt => ({ id: { $eq: evt.id}}))
// use the newly formatted newEvents in a query to get the users
// events and images
const eventsAndMedia = await strapi.db.query(modelUid).findMany({
where: {
$or: newEvents
},
populate: {image: true}
})
return sanitize.contentAPI.output(eventsAndMedia,
strapi.getModel(modelUid))
} catch(err) {
return ctx.internalServerError(err.message)
}
}
}))
thank you for ur attention, so i write a mini project that scrape news site and store main texts from them. i tried many solutions to add json in my project without have consol.log but always after scraping its show only one main text. so i show my code to you so u could help me how to have json with all three news.
const { Cluster } = require('puppeteer-cluster');
const fs = require('fs');
const launchOptions = {
headless: false,
args: [
'--disable-gpu',
'--disable-dev-shm-usage',
'--disable-web-security',
'--disable-xss-auditor',
'--disable-accelerated-2d-canvas',
'--ignore-certifcate-errors',
'--ignore-certifcate-errors-spki-list',
'--no-zygote',
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-webgl',
],
ignoreHTTPSErrors: true,
waitUntil: 'networkidle2',
};
(async() => {
// Create a cluster with 2 workers
const cluster = await Cluster.launch({
monitor: true,
concurrency: Cluster.CONCURRENCY_PAGE,
maxConcurrency: 2,
puppeteerOptions: launchOptions,
});
// Define a task (in this case: screenshot of page)
await cluster.task(async({ page, data: url }) => {
await page.setRequestInterception(true);
page.on('request', (request) => {
if (['stylesheet', 'font', 'image', 'styles','other', 'media'].indexOf(request.resourceType()) !== -1) {
request.abort();
} else {
request.continue();
}
});
await page.goto(url);
const scrapedData = await page.$eval('div[class="entry-content clearfix"]', el => el.innerText)
fs.writeFileSync('test.json', JSON.stringify(scrapedData, null, 2))
});
// Add some pages to queue
cluster.queue('https://www.ettelaat.com/?p=526642');
cluster.queue('https://www.ettelaat.com/?p=526640');
cluster.queue('https://www.ettelaat.com/?p=526641');
// Shutdown after everything is done
await cluster.idle();
await cluster.close();
})();
for gather all outputs i had to put my fs in the bottom of cluster.close
kanopyDB = []
.
.
.
kanopyDB = kanopyDB.concat(name);
.
.
.
await cluster.idle();
await cluster.close();
fs.writeFileSync('output.json', kanopyDB, 'utf8');
Im new using nodejs functions and also puppeteer. Previously I was using wkhtmltopdf but currently its options are very poor.
So, my idea was generating a pdf from a html with a first cover page (an image with full A4 width/height ), since the footer is generated from the index.js, theres no way to hide it on the FIRST page of the PDF.
//Imports
const puppeteer = require('puppeteer');
//Open browser
async function startBrowser() {
const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']});
const page = await browser.newPage();
return {browser, page};
}
//Close browser
async function closeBrowser(browser) {
return browser.close();
}
//Html to pdf
async function html2pdf(url) {
const {browser, page} = await startBrowser();
await page.goto(url, {waitUntil: 'networkidle2'});
await page.emulateMedia('screen');
//Options
await page.pdf({
printBackground: true,
path: 'result.pdf',
displayHeaderFooter: true,
footerTemplate: '<div style="width:100%;text-align:right;position:relative;top:10px;right:10px;"><img width="60px" src="data:data:image/..."'
margin : {top: '0px',right: '0px',bottom: '40px',left: '0px' },
scale: 1,
landscape: false,
format: 'A4',
pageRanges: ""
});
}
//Exec
(async () => {
await html2pdf('file:///loc/node_pdfs/givenhtml.html');
process.exit(1);
})();
My question is, is there any way to locate the first footer and hide it from the index fuction?
Thanks!
There are currently multiple bugs (see this question/answer or this one) that make it impossible to get this working.
This is currently only possible for headers using this trick (taken from this github comment):
await page.addStyleTag({
content: `
body { margin-top: 1cm; }
#page:first { margin-top: 0; }
`,
});
This will basically hide the margin on the first page, but will not work when using a bottom margin (as also noted here).
Possible Solution
The solution I recommend is to create two PDFs, one with only the first page and no margins, and another one with the remaining pages and a margin:
await page.pdf({
displayHeaderFooter: false,
pageRanges: '1',
path: 'page1.pdf',
});
await page.pdf({
displayHeaderFooter: true,
footerTemplate: '<div style="font-size:5mm;">Your footer text</div>',
margin: {
bottom: '10mm'
},
pageRanges: '2-', // start this PDF at page 2
path: 'remaining-pages.pdf',
});
Depending on how often you need to perform the task you could either manually merge the PDFs or automate it using a tool like easy-pdf-merge (I have not used this one myself).
small hint: easy-pdf-merge an pdf-merge have some "system-tools-dependencies"
I prefer pdf-lib, a plain js tool where you can use Buffers and Typescript support
My Typescript:
import {PDFDocument} from 'pdf-lib'
...
const options: PDFOptions = {
format: 'A4',
displayHeaderFooter: true,
footerTemplate: footerTemplate,
margin: {
top: '20mm',
bottom: '20mm',
},
}
const page1: Buffer = await page.pdf({
...options,
headerTemplate: '<div><!-- no header hack --></div>',
pageRanges: '1',
})
const page2: Buffer = await page.pdf({
...options,
headerTemplate: headerTemplate,
pageRanges: '2-',
})
const pdfDoc = await PDFDocument.create()
const coverDoc = await PDFDocument.load(page1)
const [coverPage] = await pdfDoc.copyPages(coverDoc, [0])
pdfDoc.addPage(coverPage)
const mainDoc = await PDFDocument.load(page2)
for (let i = 0; i < mainDoc.getPageCount(); i++) {
const [aMainPage] = await pdfDoc.copyPages(mainDoc, [i])
pdfDoc.addPage(aMainPage)
}
const pdfBytes = await pdfDoc.save()
// Buffer for https response in my case
return Buffer.from(pdfBytes)
...
I'm new to Vuejs. I want to have a form using which you can add products. The product image goes to firebase storage but how do I associate that image with the exact product in the database?
I've already set up my form, and created two methods. saveProduct() to save the products to the database and onFilePicked() to listen for changes in the input field and target the image and upload that to storage.
import { fb, db } from '../firebaseinit'
export default {
name: 'addProduct',
data () {
return {
product_id: null,
name: null,
desc: null,
category: null,
brand: null,
image: null,
}
},
methods: {
saveProduct () {
db.collection('products').add({
product_id: this.product_id,
name: this.name,
desc: this.desc,
category: this.category,
brand: this.brand
})
.then(docRef => {
this.$router.push('/fsbo/produkten')
})
},
onFilePicked (event) {
let imageFile = event.target.files[0]
let storageRef = fb.storage().ref('products/' + imageFile.name)
storageRef.put(imageFile)
}
}
}
what about this, you can use the filename, your images are going to be served as somefireurl.com/{your_file_name} on your product collection you can have an image prop with the imageFile.name.
methods: {
saveProduct (image = null) {
let productRef = db.collection('products').doc(this.product_id)
const payload = {
product_id: this.product_id,
name: this.name,
desc: this.desc,
category: this.category,
brand: this.brand
}
if (image) payload['image'] = image
return productRef
.set(payload, {merge: true})
.then(docRef => {
this.$router.push('/fsbo/produkten')
})
},
onFilePicked (event) {
let imageFile = event.target.files[0]
let storageRef = fb.storage().ref('products/' + imageFile.name)
storageRef.put(imageFile)
return this.saveProduct(imageFile.name)
}
}
That should be enough to get you started, maybe you want to try a different combination, or maybe you dont want to call saveProduct the way I set it, it's up to your use case but the idea is the same. Hope this can help you
I fixed it myself. Here's my solution. I don't know if it's technically correct but it works for my use case.
methods: {
saveProduct () {
let imageFile
let imageFileName
let ext
let imageUrl
let key
let task
db.collection('products').add({
product_id: this.product_id,
name: this.name,
desc: this.desc,
category: this.category,
brand: this.brand
})
.then(docRef => {
key = docRef.id
this.$router.push('/fsbo/produkten')
return key
})
.then(key => {
if(this.image !== null) {
this.onFilePicked
imageFile = this.image
imageFileName = imageFile.name
ext = imageFileName.slice(imageFileName.lastIndexOf('.'))
}
let storageRef = fb.storage().ref('products/' + key + '.' + ext)
let uploadTask = storageRef.put(imageFile)
uploadTask.on('state_changed', (snapshot) => {}, (error) => {
// Handle unsuccessful uploads
}, () => {
uploadTask.snapshot.ref.getDownloadURL().then( (downloadURL) => {
db.collection('products').doc(key).update({ imageUrl: downloadURL})
});
});
})
},
onFilePicked (event) {
return this.image = event.target.files[0]
}
}
I have found many solutions for uploading images and audio to Firebase storage from Ionic 3 but not a single solution for uploading video file from gallery to Firebase storage. I have been going around Camera, File, File path, Plugins,etc but not seems to find a valid solution for uploading mp4 file from my gallery to Storage.
I have tried this at first (but it has not worked):
uploadpage.ts
async selectVideo(){
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.DATA_URL,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
// encodingType: this.camera.EncodingType,
mediaType: this.camera.MediaType.ALLMEDIA
}
let result = await this.camera.getPicture(options);
result.then((uri) => {
this.spinner.load();
this.selectedVideo = uri;
}, (err) => {
// Handle error
this.helper.presentToast(err.message);
});
}
//Upload video
uploadVideo(){
if(this.selectedVideo){
this.spinner.load();
//upload task
let upload= this.api.uploadVideo(this.selectedVideo)
upload.then().then(res => {
let otherData={title:this.title,category:this.type, thumbnail:this.thumbnail}
this.api.storeInfoToDatabase(res.metadata, otherData).then(()=>{
this.spinner.dismiss();
})
})
}
}
api.ts
uploadVideo(data): AngularFireUploadTask{
let newName = `${new Date().getTime()}.mp4`;
let footballerId = JSON.parse(localStorage.getItem('data')).uid;
return this.afStorage.ref(`videos/${newName}`).putString(data);
}
storeInfoToDatabase(metaInfo, data){
let toSave={
created:metaInfo.timeCreated,
url: metaInfo.downloadURLs[0],
fullPath: metaInfo.fullPath,
contentType: metaInfo.contentType,
footballerId:'',
title: data.title || '',
type:data.type || '',
thumbnail: data.thumbnail || '',
}
toSave.footballerId = JSON.parse(localStorage.getItem('data')).uid;
return this.addVideo(toSave);
}