ExpoBarCodeScannerModule.scanFromURLAsync thrown an error - javascript

I'm trying to make a scanner in React Native that takes an image file, scans it and returns data that contains in barcode. I'm using a BarCodeScanner extension from Expo SDK.
It throws an error when I'm trying to use it.
Error looks like:
An exception was thrown while calling `ExpoBarCodeScannerModule.scanFromURLAsync` with arguments `(
1,
(
"org.iso.QRCode"
)
)`: -[__NSCFNumber length]: unrecognized selector sent to instance 0xe17787ebcc27c1d0
- node_modules/react-native/Libraries/BatchedBridge/NativeModules.js:104:55 in <unknown>
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:414:4 in __invokeCallback
- ... 4 more stack frames from framework internals
My code where I'm trying to use extension method:
file = require('./assets/image.jpg');
componentDidMount(){
BarCodeScanner.scanFromURLAsync(this. file).then(data => {
console.log(data)
}).catch(err => {
console.log(err)
})
}
Do you have any thoughts what does it mean?

A bit too late, but for anyone with simmilar problem. You can use expo ImagePicker package to select image. It will return array of objects. One of the parameters of the object is URI of the image that can be used as an input to BarCodeScanner.scanFromURLAsync method.
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: false,
quality: 1,
});
if (!result.canceled) {
let decodedBarcodeImage = await BarCodeScanner.scanFromURLAsync(result.assets[0].uri);
// Handle result data
console.log(decodedBarcodeImage);
} else {
// Handle canceled result
console.log('You did not select any image.');
}
};

Related

Delete a batch of docs using admin SDK and callable cloud function in most similar way to client SDK?

I have an array of docs ids that I want to delete in using a cloud function, my code looks like the following :
//If the user decieds on deleting his account forever we need to make sure we wont have any thing left inside of db after this !!
// incoming payload array of 3 docs
data = {array : ['a302-5e9c8ae97b3b','92c8d309-090d','a302-5e932c8ae97b3b']}
export const deleteClients = functions.https.onCall(async (data, context) => {
try {
// declare batch
const batch = db.batch();
// set
data.arr.forEach((doc: string) => {
batch.delete(db.collection('Data'), doc);
});
// commit
await batch.commit();
} catch (e) {
console.log(e);
}
return null;
});
I am getting a syntax error on batch.delete how to pass the right arguments in to the batch delete to reference that doc I want to submit for deletion before commit ?
Delete takes a single param, the doc ref of the doc to be deleted.
data.arr.forEach((docId: string) => {
batch.delete(doc(db, "Data", docId));
});
There are several errors in your code:
data.arr.forEach() cannot work wince your data object contains one element with the key array and not the key arr.
You are mixing up the syntax of the JS SDK v9 and the Admin SDK. See the write batch Admin SDK syntax here.
You need to send back some data to the client when all the asynchronous work is complete, to correctly terminate your CF.
You do return null; AFTER the try/catch block: this means that, in most of the cases, your Cloud Function will be terminated before asynchronous work is complete (see the link above)
So the following should do the trick (untested):
const db = admin.firestore();
const data = {array : ['a302-5e9c8ae97b3b','92c8d309-090d','a302-5e932c8ae97b3b']};
export const deleteClients = functions.https.onCall(async (data, context) => {
try {
const batch = db.batch();
const parentCollection = db.collection('Data')
data.array.forEach((docId) => {
batch.delete(parentCollection.doc(docId));
});
// commit
await batch.commit();
return {result: 'success'} // IMPORTANT, see explanations above
} catch (e) {
console.log(e);
// IMPORTANT See https://firebase.google.com/docs/functions/callable#handle_errors
}
});

How to use expo-background-fetch to fetch a specific url every 60 seconds?

I have tried almost any example provided in docs but I can't run it.
I want to make a request to a specific url with axios (or fetch method) every 60 seconds and process the data in the background. In other words I want something common like:
this.getPageInterval = setInterval(() => {
const json = await (await fetch(this.fetchURL)).json();
...// etc
}, 60000)
can happen when the app is in background.
my console.log says 'task registered' but it feels like this block of code never triggers(global scope):
BackgroundFetch.setMinimumIntervalAsync(5);
const taskName = 'test-background-fetch';
TaskManager.defineTask(taskName, async () => {
console.log('background fetch running');
try {
const receivedNewData = await (await fetch(this.fetchUri)).json();
console.log('receivedNewData', receivedNewData)
return receivedNewData ? BackgroundFetch.Result.NewData : BackgroundFetch.Result.NoData;
let isRegistered = await TaskManager.isTaskRegisteredAsync(taskName);
console.log("isRegistered: ", isRegistered);
} catch (error) {
return BackgroundFetch.Result.Failed;
}
console.log("BackgroundFetch.Result.NewData", BackgroundFetch.Result.NewData);
return BackgroundFetch.Result.NewData;
});
and in my class component:
await BackgroundFetch.registerTaskAsync(taskName, {
setMinimumIntervalAsync: 5,
stopOnTerminate: false
});
await BackgroundFetch.setMinimumIntervalAsync(5);
alert('task registered');
console.log('task registered');
It seems you're not registering your task in your class component. Is taskname defined as 'test-background-fetch' in your component? You need to call exactly the same task name.
Also some phones are somewhat problematic with background tasks. I never tried it on expo, but on React Native some brands had to go through some extra setup.
Also note that in the documentation it says it only works when backgrounded. Terminated apps wont run the background function.

Unable to write images from firebase to a pdf using pdfkit and node.js

Trying to generate pdf using data from firebase but unable to write images to the pdf. The main function is a async function and have await operator for the function, which is used to fetch the image. But facing the following error:
Error: stream.push() after EOF
Please advice.
I tried to add await for the axios which is used to get the image and even tried to write it inside an async function.Then i tried to write the whole thing outside the main function and call it but the EOF issue is again displayed.
//this is the main function //
async function getPDF() {
...
...
//This is the part where I try to write images from firebase ///
await questionNumber.get().then(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
i++;
var exteriorQuestionsData = doc.data();
for(x=0;x<extFormDataAnswers[i-11].exteriorQuestionsImages.length;x++){
if(extFormDataAnswers[i-11].exteriorQuestionsImages!= undefined || extFormDataAnswers[i-11].exteriorQuestionsImages!= [] ) {
img_url = extFormDataAnswers[i-11].exteriorQuestionsImages[x].uri
axios.get(img_url, { responseType: 'arraybuffer' }).then(response => {
var my_img = Buffer.from(response.data);
pdf_doc.image(my_img,{ fit: [300, 300] })
.fontSize(18)
.fillColor('#426998')
.font('Helvetica-Bold')
.moveDown(0.2)
.lineWidth(0.5);
});
}
}
});
});
....
....
The expected result is that the images should be displayed in the pdf but the following error is encountered Error: stream.push() after EOF

Expo FileSystem.moveAsync location is not moveable?

I'm working on react native App using expo API, the App basically takes a picture then the App crop it using ImageEditor.cropImage, finally copy the picture from cache to another location. the code:
takePicture = async function() {
if (this.camera) {
this.camera.takePictureAsync().then(async (data) => {
cropdata = {
offset:{x:0, y:0},
size:{width:100, height:100},
};
await ImageEditor.cropImage(
data.uri,
cropdata,
async (uri) => {
FileSystem.moveAsync({
from: uri,
to: `${FileSystem.documentDirectory}photos/Photo_${this.state.photoId}.jpg`,
}).then(() => {
this.setState({
photoId: this.state.photoId + 1,
});
Vibration.vibrate();
});
},
(error) => {
console.log(error);
}
);
});
}
};
But the following error is shown:
[Unhandled promise rejection: Error: Location
'file:///data/user/0/host.exp.exponent/cache/ReactNative_cropped_image_574763720.jpg'
isn't movable.]
any idea?
Expo’s FileSystem module can copy/move/etc. files that are previously saved in the app’s scope (for example via ImagePicker or using Asset.loadAsync). ImagerEditor is a core React Native functionality and it saves your image to a file that is outside Expo’s scope, thus FileSystem cannot perform actions on this file. more on this can be found here:
https://forums.expo.io/t/where-does-camera-takepictureasync-save-photos/6475/7
so instead of using ImageEditor.cropImage() one should use expo ImageManipulator.

Firebase firestore how to get reference data without additional request?

When I have fetched places that we can see in screenshot below, I need get their data, but it's reference to data, I can get the data without additional request like place.ref.data()? If I have 30 places, should I make 30 requests, really? I use react native and the ref object has type DocumentReference https://rnfirebase.io/docs/v3.1.x/firestore/reference/DocumentReference
You need to create your own populate method.
Here's one example I made where my collection eventSchedule has references to events, then I have the array of events and I want to get the events from each eventSchedule... That's how I did:
...
const docRef = db.collection("eventSchedule").doc(dayName);
try {
const doc = await docRef.get();
if (doc && doc.exists) {
const eventSchedule = doc.data();
if (eventSchedule.activeEvents) {
const activeEventsRefs = eventSchedule.activeEvents;
eventSchedule.activeEvents = [];
await activeEventsRefs.reduce(
async (promise: any, event: any) => {
await promise;
const childDoc = await event.get();
if (childDoc) {
eventSchedule.activeEvents.push(childDoc.data());
}
},
Promise.resolve()
);
}
} else {
logMessage += `No docs found for eventSchedule for today - ${dayName}`;
}
} catch (error) {
logMessage += `Error getting document ${JSON.stringify(error)}`;
}
So I used reducer to handle the promises. It works like a charm and it was the simplest "manual" way of doing this.
Also if you use React + Redux + Firebase, you can check the library react-redux-firebase that already implements a lot of stuff including the populate that is, similar to the MongoDB populate and the SQL Join:
http://react-redux-firebase.com/docs/populate.html

Categories