We are getting Sentry reports from our Android customers who get errors during makeDirectoryAsync(). The error is:
Error: Directory 'file:///data/user/0/companyName/cache/ExperienceData/%2540companyName%252FappName/content/' could not be created..
The issue seem only to be related to users with Huawei phones (SKD 24-27).
The error accrue during our initial setup of the cache and this is the code.
const TEMP_DIR = FileSystem.cacheDirectory
const DIR_PATH = `${TEMP_DIR}${folderName}/`
return FileSystem.getInfoAsync(DIR_PATH).then(info => {
if (!info.exists) {
return FileSystem.makeDirectoryAsync(DIR_PATH, {
intermediates: true,
}).then(() => {
[...]
})
}
[...]
})
Expo sdk => 30.0.0
related issues:
https://forums.expo.io/t/makedirectoryasync-error-could-not-be-created/11916
https://github.com/expo/expo/issues/1980
We have not detached our app from expo.
thankful for any help.
Holger
Related
I'm trying to deploy my first next.js project on vercel. Locally everything is working.
My problem: When deploying (command: next build) the web app I get the message "Generating static sites (0/2000)" and then nothing happens. The deployment is cancelled after 1h (time expiration).
The problem is somewhere in the (simplified) code below. Here's why: when I deploy the project without the part that follows after const content the deployment is successful - so basically instead of having singleProductResponse AND contentResponse as props, I only have singleProductResponse..
I'm a little stuck and don't know how to solve this. Can someone tell me what I'm doing wrong? Thanks a lot!!
const Item = ({ singleProductResponse, contentResponse }) => {
const router = useRouter();
if (router.isFallback) {
return <div>Loading...</div>;
}
return (
<div className={styles.section}>
<Overview
singleProductResponse={singleProductResponse}
contentResponse={contentResponse}
/>
</div>
);
};
export async function getStaticPaths() {
const itemResponse = await knex("Items");
const paths = itemResponse.map((product) => ({
params: {
brand: product.brand,
item: product.item,
},
}));
return {
paths,
fallback: true,
};
}
export async function getStaticProps({ params }) {
try {
const itemData = await knex("Items").where(
"item",
"like",
`${params.item}`
);
const singleProductResponse = itemData[0];
//!!!!!!!!!when leaving the following part out: deployment is successful!!!!!!!!!!!!
const content = itemData[0].contentList;
const splitContent = content.split(", ");
const contentArray =
typeof splitContent === "string"
? [splitContent]
: splitContent;
const result = await knex("Cos")
.leftJoin("Actives", "Cos.content", "ilike", "Actives.content")
.leftJoin("Alcohol", "Cos.content", "ilike", "Alcohol.content")
.column([
"Cos.content",
"function",
"translationPlant",
"categoryAlcohol",
])
.where((qb) => {
contentArray.forEach((word) => {
qb.orWhere("Cos.content", word);
});
return qb;
});
return {
props: { singleProductResponse, contentResponse },
revalidate: 1,
};
} catch (err) {
console.log(err);
return {
redirect: {
destination: "/",
permanent: false,
},
};
}
}
UPDATE
After digging deeper: I think the problem is that the part after const content is too slow in building process.
When running next build, as well as when deploying on vercel the building process stops after approx. 1h. I suppose this is because of the limit of 45min for building process.
The last message I get is "Generating static pages (1000/2000)" (in vercel and locally) and "Build failed" (vercel). I don't get any other error-messages (also not in the catch block).
I've already tried to optimize the part after const content (each table has an index (clustered indexes -> primary keys), I've redesigned the tables (only 4 tables to join, instead of 6), eliminated everything unnecessary in the query and checked that the database (postgres hosted on heroku - hobby-basic) is also in the US). The performance is better, but still not enough. Does anyone have some suggestions for improvement? TTFB might be a somehow slow.
I am using the following code for checking if my react application has a camera permission:-
checkForCameraPermission = () => {
try {
navigator.permissions.query({ name: 'camera' }).then(permissionStatus => {
// granted, denied, prompt
switch (permissionStatus.state) {
case 'denied':
// eslint-disable-next-line no-alert
// alert(
// 'You need to provide camera permission and reload page to continue futher with KYC journey or else please download the EarlySalary App to continue further.'
// );
this.setState({
cameraDialogStatus: true
});
break;
default:
break;
}
// eslint-disable-next-line no-param-reassign
permissionStatus.onchange = () => {
console.log(`Permission changed to ${this.state}`);
};
});
} catch (error) {
console.log('camera error', error);
// alert('TEST');
this.setState({ isShowTestDialog: true });
}
};
I am using this in component did mount lifecycle method it works fine on most of the browsers but on some browsers it is not supported. So I tried finding out why it wasn't working on some devices and I finally got my answer with the MDN web docs at the following link:-
[https://developer.mozilla.org/en-US/docs/Web/API/Navigator/permissions][1]
Is there a better approach that I can take as my react application is being used on Desktops as well as on mobile phone's and I would like the application to work as expected on all the devices and if not show why it is failing?
Any help or suggestion is much appreciated. Thank you for your time and support.
Upgrading from Electron v2.0.3 to the latest relase v5.0.1
When I try running electron, I get the following error:
TypeError: app.makeSingleInstance is not a function
I believe this is because the api has changed. I cannot find what the equivalent for this would be. Any help would be appreciated!
main.js (was working fine in v2.0):
let appInstance= null,
mainWindow = null,
appInstance = app.makeSingleInstance(() => {
if (mainWindow) {
if (mainWindow.isMinimized()) {
mainWindow.restore();
}
mainWindow.focus();
}
})
Yes, the API has changed since Electron 4.0: Planned Breaking API Changes (4.0):
app.makeSingleInstance
// Deprecated
app.makeSingleInstance((argv, cwd) => {
/* ... */
})
// Replace with
app.requestSingleInstanceLock()
app.on('second-instance', (event, argv, cwd) => {
/* ... */
})
More details are available in the documentation for the requestSingleInstanceLock() method and the 'second-instance' event.
I am trying to save the base64 string to the gallery. When I invoke this plugin my code get's crashed. Here is the link I used to check.
code I use
let options:Base64ToGalleryOptions = { prefix: '_img',mediaScanner: true }
//after the below line my gets close automatically any idea
this.base64ToGallery.base64ToGallery(base64Image[1],options)
.then(
res => {
debugger
console.log('Saved image to gallery ', res)
},
err => {
debugger
console.log('Error saving image to gallery ', err)
});
I am not able to debug
I am not able to understand why my app closes automatically after hitting this code
Update:
After installing this particular version of the plugin
ionic cordova plugin add cordova-base64-to-gallery#2.0.2
and moving my code to platform
this.platform.ready().then(() => {
this.base64ToGallery.base64ToGallery(base64Image,options)
.then(
res => {
console.log('Saved image to gallery ', res);
this.navCtrl.pop();
},
err => { //For ios i am getting as `plugin_not_installed`
console.log('Error saving image to gallery ', err);
this.navCtrl.pop()
});
})
But this same code is not working for ios according to the doc i have installed the same version which supports ios also (2.0.2) but it looks something is missing if any please let me know
Since you are unable to debug here are three problems I ran across until I got it to work, most likely the second problem if on Android or the third problem if on iOS.
1) Error saving image to gallery cordova_not_available
Fix for this was to create a project that had cordova baked in with the command ionic start blank --cordova
2) Error saving image to gallary Error while saving image I got this error message on an Android device. I looked at their code implementation here https://github.com/Nexxa/cordova-base64-to-gallery/blob/2f531aaa0bf17b900cf6bd9704082e72f183d325/src/android/Base64ToGallery.java
Saw that they have not done anything regarding WRITE_EXTERNAL_STORAGE permissions.
My solution was to add AndroidPermissions and check for WRITE_EXTERNAL_STORAGE permissions at runtime.
hasWriteAccess: boolean = false;
constructor(private base64ToGallery: Base64ToGallery,
private androidPermissions: AndroidPermissions) {
}
ionViewWillEnter() {
this.checkPermissions();
}
checkPermissions() {
this.androidPermissions
.checkPermission(this.androidPermissions
.PERMISSION.WRITE_EXTERNAL_STORAGE)
.then((result) => {
console.log('Has permission?',result.hasPermission);
this.hasWriteAccess = result.hasPermission;
},(err) => {
this.androidPermissions
.requestPermission(this.androidPermissions
.PERMISSION.WRITE_EXTERNAL_STORAGE);
});
if (!this.hasWriteAccess) {
this.androidPermissions
.requestPermissions([this.androidPermissions
.PERMISSION.WRITE_EXTERNAL_STORAGE]);
}
}
saveImage() {
if (!this.hasWriteAccess) {
this.checkPermissions();
}
let options: Base64ToGalleryOptions = {
prefix: '_img',
mediaScanner: true
};
this.base64ToGallery
.base64ToGallery(this.base64Data, options).then(
res => console.log('Saved image to gallery:', res),
err => console.log('Error saving image to gallery:', err)
);
}
3) This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data.
Solution is to add NSPhotoLibraryAddUsageDescription to project_name/config.xml nested between <platform name="ios"> and </platform>
<config-file parent="NSPhotoLibraryAddUsageDescription" target="*-Info.plist">
<string>Saves images from base64 to your Photo Library</string>
</config-file>
I'm developing web push notification on my website. I follow the Web Push Notifications of Google and The Service Worker Cookbook of Mozilla.
I have tested on the Google Chrome v50+ and everything is working but I will get the error below on Firefox 44, 45, 46, 52, latest Firefox (version 57.0.4 64 bit) when calling navigator.serviceWorker.register('./push-service-worker.js') function.
TypeError: ServiceWorker script at http://localhost:9600/push-service-worker.js for scope http://localhost:9600/ encountered an error during installation.
This is my code:
Register ServiceWorker in controller.js
navigator.serviceWorker.register('push-service-worker.js')
.then((registration) => {
return registration.pushManager.getSubscription()
.then((subscription) => {
if (subscription) {
return subscription;
}
var subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: buildApplicationServerKey(),
};
return registration.pushManager.subscribe(subscribeOptions);
});
})
.then((subscription) => {
sendSubscriptionToServer(subscription);
})
.catch((err) => {
console.log('Unable to subscribe to push: ', err);
});
push-service-worker.js
'use strict';
self.addEventListener('push', (event) => {
var payload = event.data.json();
var title = payload.title || 'Title';
event.waitUntil(
self.registration.showNotification(title, {
body: payload.body,
icon: './common/images/notification-icon-192x192.png',
image: payload.image || '',
})
);
});
self.addEventListener('notificationclick', (event) => {
event.notification.close();
var urlToOpen = new URL('/', self.location.origin).href;
event.waitUntil(
clients.matchAll({
type: 'window',
includeUncontrolled: true,
})
.then((windowClients) => {
var matchingClient = null;
for (var i = 0; i < windowClients.length; i++) {
var windowClient = windowClients[i];
if (windowClient.url === urlToOpen) {
matchingClient = windowClient;
break;
}
}
if (matchingClient) {
return matchingClient.focus();
} else {
return clients.openWindow(urlToOpen);
}
})
);
});
Directory structure
./root
---- manifest.json
---- push-service-worker.js
---- src
---- controller.js
Thank for helping!
As wanderview said at here:
FWIW, you should always use a separate profile for each channel (release/beta/dev-edition/nightly). We're working on making it work like that out-of-the-box, but its not ready yet.
This problem is encountered when I use one profile for multiple Firefox version. To fix this issue go to about:support and click Refresh Firefox. If it doesn't work, you can go to about:profiles, click Create new profile, and then Launch profile in new browser.
In my case, this was caused by Firefox not being able to access the serviceworker.js file.
The server I was hosting it on had a permissions check based on cookies, and in this case Firefox was not sending the cookie as I believe it was considered a cross-site script.
On the server, I made the serviceworker.js file accessible publicly, and then Firefox could register the service worker.
It was particularly difficult to notice this, because the Firefox Developer Tools did not show the Forbidden response in the Console, nor did it even show any request for serviceworker.js in the Network tab.
Therefore, presumably the TypeError is in fact a generic error and should be read as 'something went wrong registering the Service Worker'.