I'm trying to share a local file in React Expo using Sharing.shareAsync(). Retrieved photo info using MediaLibrary.getAssetInfoAsync() (on Android):
"filename": "IMG_20200414_190459.jpg",
"height": 2074,
"id": "896",
"localUri": "file:///storage/emulated/0/DCIM/Camera/IMG_20200414_190459.jpg",
"location": null,
"mediaType": "photo",
"modificationTime": 1586905500000,
"uri": "file:///storage/emulated/0/DCIM/Camera/IMG_20200414_190459.jpg",
"width": 4608,
Calling Sharing.shareAsync(photo.localUri, {mimeType: 'image/jpeg'} I get the error Failed to share the file: Failed to find configured root that contains /storage/emulated/0/DCIM/Camera/IMG_20200414_190459.jpg. So I tried removing one of the slashes after file: and get the error Not allowed to read file under given URL.
App has CAMERA_ROLL and CAMERA permissions and app.json includes:
"android": {
"permissions": [
"CAMERA",
"CAMERA_ROLL",
"READ_EXTERNAL_STORAGE",
"WRITE_EXTERNAL_STORAGE"
]
}
Expo docs say I should be able to share a local file. Not sure what I'm doing wrong or what to try next. TIA.
This is a problem with the share API. You can get over this using the expo-image-manipulation.
As an example:
import * as ImageManipulator from "expo-image-manipulator";
const openShareDialogAsync = async () => {
let imageProc = await ImageManipulator.manipulateAsync(yourImageUri);
// this returns an object including the uri
await Sharing.shareAsync(imageProc.uri);
}
It looks like this may be a bug in the Sharing API. You can work around it for now by copying the file to your document directory and then sharing from there. Here's an example: https://snack.expo.io/#notbrent/share-media-library-photo
Relevant code from that example below:
// Placeholder for getting asset from MediaLibrary
let results = await MediaLibrary.getAssetsAsync({ first: 1 });
let asset = results.assets[0];
// Use FileSystem to copy the image from its original location to the app document directory
let assetUriParts = asset.uri.split("/");
let assetName = assetUriParts[assetUriParts.length - 1];
let uri = `${FileSystem.documentDirectory}/${assetName}`;
await FileSystem.copyAsync({
from: asset.uri,
to: uri,
});
// Share the image from the uri that you copied it to
Sharing.shareAsync(uri);
Related
I am setting a universal link with a React Native app. It is routing to my app, but I am not getting the behavior that I expect.
Here is the component piece of my AASA file.
"components": [
{
"#": "no_universal_links",
"exclude": true,
"comment": ""
},
{
"/": "/oauth*",
"comment": "Redirect URL for OAuth"
}
]
The AASA file is hosted at a url that I own. I have installed the app on my phone, pulled the sysdiagnose file off my device and verified that my app is downloading the AASA file, so the routes should be working on my device.
In my React Native code, I have an event watcher looking at the urls that are being used to open the app. I am using the expo-linking library to log the url and params.
function handleLink(event) {
const data = Linking.parse(event.url);
console.log(data, data);
}
React.useEffect(() => {
Linking.getInitialURL().then((res) => {
console.log(res);
});
const listener = Linking.addEventListener("url", handleLink);
return () => listener.remove();
}, []);
When I route to <url>/oauth in safari, it gives the options to open up my app. When I use the app option the system then routes to my app. The code above then logs out the url and query params from the url that opened the app.
When I try to use the universal link for the actual OAuth redirect (not from Safari), it opens up my app, but no url is logged out from the event, so the event is not being hit at all. Also, it looks like it is opening up some kind of webpage in my app, but the fact is I really don't know what it is doing.
In short, when using my app with another service calling the url, it opens up my app, but I only see a white page and only know I am on my app by looking at the title of the app.
If anyone could give me any direction, I would be really grateful.
Problem:
When uploading an image from Strapi (the Media Library (UI)) it shows me the error: VipsJpeg: Premature end of input file.
I tried to change the format from jpg to png but it still shows the same error. On the other hand, I was testing with other images (jpg/png format). and it uploads correctly.
I would like to know the reason for the error, and if there is any solution.
I will appreciate your answer
Uploading image to strapi: Media Library
Image Info
JPEG image - 19 KB
Dimensions: 750 × 938
Error:
Error: VipsJpeg: Premature end of input file
config/plugins.js
Default configuration, provided by strapi
module.exports = ({ env }) => ({
upload: {
config: {
breakpoints: {
xlarge: 1920,
large: 1000,
medium: 750,
small: 500,
xsmall: 64,
},
},
},
});
It Looks like this is an issue in sharp , Strapi server stop when it encounter this issue and because of that it return network error 502 .
to solve it in my code i had to extend the plugin-upload code and to change this const in that plugin to stop causing server to fail , then image can uploaded successfully , maybe without proper optimization but without failing .
on node_module/#strapi/plugin-upload/server/services/image-manipulation.js change this const
const transformer = sharp();
to this
const transformer = sharp({ failOnError: false });
Steps to Apply it to Strapi as plugin extension :
1 - extend the plugin-upload plugin by creating ( upload ) folder within src/extensions folder ( create extensions folder if it does not exist )
2 - Create a file named ( strapi-server.js ) with this content to overwrite the image-manupilation service :
'use strict';
const imageManipulate = require('./server/services/image-manipulation')
module.exports = (plugin) => {
plugin.services['image-manipulation'] = imageManipulate;
return plugin;
};
3 - Copy ( utils folder + services/image-manipulation.js) from node_module/#strapi/plugin-upload/server to your extensions folder .
4 - Edit transformer const in image-manipulation.js as discussed before .
For more information about the sharp issue see here : https://github.com/lovell/sharp/issues/1859
For more information about Extending Strapi Plugin see here : https://docs.strapi.io/developer-docs/latest/development/plugins-extension.html
I have tried many different ideas, but am unable to find how I can get the image of an NFT with an HTTP request. I tried to find an HTTP API that returns the token URI, but was unable to find anything. without the token URI I am unable to find the image on ipfs.
If you get the "tokenUri" of the NFT and paste it to the browser
ipfs://tokenUriHERE
You will see the NFT metadata in a json format like this.
{
"name": "name it",
"image": "ipfs://QmR36VFfo1hH2RAwVs4zVJ5btkopGip5cW7ydY4jUQBrKW",
"description": "description",
"attributes": [
{
"trait_type": "Artist",
"value": "value"
},
] }
If you get the image URL and paste it to the browser you will see the image.
If you want to write a code to fetch data, just send get request to ipfs://tokenUriHERE get the JSON, retrieve the image and then get the image.
Or you can use libraries. In javascript, web3.storage
import { Web3Storage } from 'web3.storage'
const token = process.env.API_TOKEN
const client = new Web3Storage({ token })
async function retrieveFiles () {
const cid =
'bafybeidd2gyhagleh47qeg77xqndy2qy3yzn4vkxmk775bg2t5lpuy7pcu'
// You can fetch data using any CID, even from IPFS Nodes or Gateway URLs!
const res = await client.get(cid)
const files = await res.files()
for (const file of files) {
console.log(`${file.cid}: ${file.name} (${file.size} bytes)`)
}
}
retrieveFiles()
If you're building with React, there's a great library use-nft from spectre.xyz that helps abstract away the inconsistent formatting of NFT metadata to give you the relevant URL for displaying the image.
You can install it with:
npm install --save use-nft ethers
Before using it, you will have to wrap your app in a provider as shown here but the actual usage is very easy.
function Nft() {
const { loading, error, nft } = useNft(
"0xd07dc4262bcdbf85190c01c996b4c06a461d2430", // NFT contract address
"90473" // token ID
)
// nft.loading is true during load.
if (loading) return <>Loading…</>
// nft.error is an Error instance in case of error.
if (error || !nft) return <>Error.</>
// You can now display the NFT metadata.
return (
<section>
<h1>{nft.name}</h1>
<img src={nft.image} alt="" />
<p>{nft.description}</p>
<p>Owner: {nft.owner}</p>
<p>Metadata URL: {nft.metadataUrl}</p>
</section>
)
}
I am following this library to implement In App Purchase for react native project.
Project info:-
inside package.json
"dependencies": {
"react": "16.11.0",
"react-native": "0.61.5",
"react-native-iap": "^4.4.9"
},
And I am trying to get product list,
import * as RNIap from 'react-native-iap';
const itemSkus = Platform.select({
ios: [
'com.cooni.point1000',
'com.cooni.point5000', // dooboolab
],
android: [
'com.example.coins100'
]
});
try {
const result = await RNIap.initConnection();
await RNIap.consumeAllItemsAndroid();
console.log('result', result);
if(result == true){
console.log("itemSkus>>>", itemSkus)
const products = await RNIap.getSubscriptions(itemSkus);
console.log("getting_products>>>", products)
this.setState({ products });
}
} catch(err) {
console.warn(err); // standardized err.code and err.message available
}
I am getting true for initConnection but getting [] (empty array) for getSubscriptions and also for getProducts()
By the way, I am getting empty array also for project which is in testFlight for using subscription ids that I have created. Those are in "Waiting for review state"
Is it not possible to get result using above test iap ids and ids that are in "Waiting for review state"?
How can I get response either using example or real ids?
Any help should be appreciable.
These are the possible solutions please check
The products are not in the 'Ready To Submit' state (make sure you've added the screenshot).
You haven't signed your Paid Applications Agreement in App Store Connect
You're testing on an emulator instead of a physical device.
My experience with RN-IAP for iOS was that it is super-unreliable, and plagued with issues where it works differently from documentation, and differently from Android version. The best solution I found was to switch to RevenueCat service for purchase management - that works great, after about an year of use I have not encountered any issues or differences between Android and iOS.
I was having the same problem and found that it worked if I removed the bundle ID from iOS product ID.
const itemSkus = Platform.select({
ios: [
'point1000',
'point5000', // dooboolab
],
android: [
'com.example.coins100'
]
});
I'm trying out Prisma and React Native right now. Currently I'm trying to upload images to my db with the package _apollo-upload-client (https://github.com/jaydenseric/apollo-upload-client). But it's not going so well.
Currently I can select an image with the ImagePicker from Expo. And then I'm trying to do my mutation with the Apollo Client:
await this.props.mutate({
variables: {
name,
description,
price,
image,
},
});
But I get the following error:
Network error: JSON Parse error: Unexpected identifier "POST"
- node_modules/apollo-client/bundle.umd.js:76:32 in ApolloError
- node_modules/apollo-client/bundle.umd.js:797:43 in error
And I believe it's from these lines of code:
const image = new ReactNativeFile({
uri: imageUrl,
type: 'image/png',
name: 'i-am-a-name',
});
Which is almost identical from the their example, https://github.com/jaydenseric/apollo-upload-client#react-native.
imageUrl is from my state. And when I console.log image I get the following:
ReactNativeFile {
"name": "i-am-a-name",
"type": "image/png",
"uri": "file:///Users/martinnord/Library/Developer/CoreSimulator/Devices/4C297288-A876-4159-9CD7-41D75303D07F/data/Containers/Data/Application/8E899238-DE52-47BF-99E2-583717740E40/Library/Caches/ExponentExperienceData/%2540anonymous%252Fecommerce-app-e5eacce4-b22c-4ab9-9151-55cd82ba58bf/ImagePicker/771798A4-84F1-4130-AB37-9F382546AE47.png",
}
So something is popping out. But I can't get any further and I'm hoping I could get some tips from someone.
I also didn't include any code from the backend since I believe the problem lays on the frontend. But if anyone would like to take a look at the backend I can update the question, or you could take a look here: https://github.com/Martinnord/Ecommerce-server/tree/image_uploads.
Thanks a lot for reading! Cheers.
Update
After someone asked after the logic in the server I have decided to past it below:
Product.ts
// import shortid from 'shortid'
import { createWriteStream } from 'fs'
import { getUserId, Context } from '../../utils'
const storeUpload = async ({ stream, filename }): Promise<any> => {
// const path = `images/${shortid.generate()}`
const path = `images/test`
return new Promise((resolve, reject) =>
stream
.pipe(createWriteStream(path))
.on('finish', () => resolve({ path }))
.on('error', reject),
)
}
const processUpload = async upload => {
const { stream, filename, mimetype, encoding } = await upload
const { path } = await storeUpload({ stream, filename })
return path
}
export const product = {
async createProduct(parent, { name, description, price, image }, ctx: Context, info) {
// const userId = getUserId(ctx)
const userId = 1;
console.log(image);
const imageUrl = await processUpload(image);
console.log(imageUrl);
return ctx.db.mutation.createProduct(
{
data: {
name,
description,
price,
imageUrl,
seller: {
connect: { id: userId },
},
},
},
info
)
},
}
Solution has been found.
I am a little embarrassed that this was the problem that I faced and I don't know if I should even accept this answer because of awkward I felt when I fixed the issue. But....
There was nothing wrong with my code, but there was a problem with the dependencies versions. I tried to backtrack everything on my app, so I decided to start from the beginning and create a new account. I expected it to work just fine, but I got this error:
Error: Cannot use GraphQLNonNull "User!" from another module or realm.
Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.
https://yarnpkg.com/en/docs/selective-version-resolutions
Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.
Then I understand that something (that I didn't think of) was wrong. I checked my dependencies versions and compared them with Graphcool's example, https://github.com/graphcool/graphql-server-example/blob/master/package.json. And I noticed that my dependencies was outdated. So I upgraded them and everything worked! So that was what I had to do. Update my dependencies.
Moral of the story
Always, always check your damn dependencies versions...
Crawling through your code, I have found this repository, which must be the front-end code if I am not mistaken?
As you've mentioned, apollo-upload-server requires some additional set-up and same goes for the front-end part of your project. You can find more about it here.
As far as I know, the problematic part of your code must be the initialisation of the Apollo Client. From my observation, you've put everything Apollo requires inside of src/index folder, but haven't included Apollo Upload Client itself.
I have created a gist from one of my projects which initialises Apollo Upload Client alongside some other things, but I think you'll find yourself out.
https://gist.github.com/maticzav/86892448682f40e0bc9fc4d4a3acd93a
Hope this helps you! 🙂