Tipsi-Stripe creating a source from a token - react-native

I am trying to use tipsi-stripe to create a source which I will send to my server. I get the token fine with following code but creating a source from the token
throws an error
try {
this.setState({ loading: true, token: null })
const token = await stripe.paymentRequestWithCardForm({
// Only iOS support this options
smsAutofillDisabled: true,
requiredBillingAddressFields: 'full',
prefilledInformation: {
billingAddress: billingAddress,
},
})
this.setState({ 'token': token })
var strToken=this.state.token;
console.log(strToken);
const params = {
type:'card',
token:strToken
}
const source = await stripe.createSourceWithParams(params)
Error is as follows
[Error: The payment method `card` requires the parameter: card[number].]
What am I doing wrong?

Related

react native iOS Apollo - TypeError: Network request failed - URI accessible from outside the app

I've got a graphql URI that I need to query from my react-native App. This URI is public and I've got access to its schema/structure when I simply type the URI in my browser.
As soon as I try to query it from my code, I get the [TypeError: Network request failed] error (logs are created in the function that builds my ApolloClient).
I've checked the URI a million time, it's the same as the one I put in my browser, and the one I've used in the past to successfully query the DB.
This is the client-building function:
export function initServices({
uri,
authToken,
mockMeanDelay = 400,
mock = false,
mockScenarios = [],
}: Options): Services {
let mockRemoteController = null;
let linkToOutsideWorld: ApolloLink;
const messageBus = createMessageBus();
const terminatingLink = createUploadLink({
uri: CORRECT_URI_HERE,
})
const authLink = setContext(async (_, { headers }) => {
const token = await authToken();
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
},
};
});
linkToOutsideWorld = from([authLink, withCustomScalars(), terminatingLink]);
const errorReportingLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
// eslint-disable-next-line no-console
console.error(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
// eslint-disable-next-line no-console
if (networkError) console.error(`[Network error]: ${networkError}`);
});
const link = ApolloLink.from([errorReportingLink, linkToOutsideWorld]);
const fragmentMatcher = new IntrospectionFragmentMatcher({
// #ts-ignore
introspectionQueryResultData: introspectionResult,
});
const apolloClient = new ApolloClient({
link,
defaultOptions: {
watchQuery: {
// We prefer using a `cache-and-network` policy so that screens
// are always in sync with backend
// Otherwise, the default policy would not fetch the server
// data from server if the result of query is already in cache
fetchPolicy: 'cache-and-network',
},
},
cache: new InMemoryCache({
cacheRedirects: {
Query: {
// #ts-ignore issue in typing of cacheRedirects
userById: (_, { userId }: QueryUserByIdArgs, { getCacheKey }) =>
getCacheKey({ __typename: 'User', id: userId }),
// #ts-ignore issue in typing of cacheRedirects
gatheringSpaceById: (
_,
{ gatheringSpaceId }: QueryGatheringSpaceByIdArgs,
{ getCacheKey },
) =>
getCacheKey({
__typename: 'GatheringSpace',
id: gatheringSpaceId,
}),
// #ts-ignore issue in typing of cacheRedirects
gatheringInstanceById: (
_,
{ gatheringInstanceId }: QueryGatheringInstanceByIdArgs,
{ getCacheKey },
) =>
getCacheKey({
__typename: 'GatheringInstance',
id: gatheringInstanceId,
}),
},
},
fragmentMatcher,
}),
});
return { apolloClient, messageBus, mockRemoteController };
}
When I replace the URI with another publicly available one, it seems to work so my guess is that there's an issue with the back-end side. But how is it possible that I have full access to the schema and queries with my browser?
Any tips to help debugging are welcome too!
Thanks for your help!

Problem with Authentication using Apollo and React-native

I have this authentication issue
The registration works perfectly and the servers take the registration data: User password email and number. After this step, I have OTP verification
I got the pin code and run the verification mutation.
On the verification, I got the error :
You are not authenticated
And the all process stops because I am not verified
Here is the code for the react-native part
const VERIFY = gql
mutation($token: String!, $kind: TokenKind!) {
verify(token: $token, kind: $kind)
}
const VerificationScreen: React.FC < any > = (props) => {
const token = (props as any).route.params.token;
const [loading, setLoading] = React.useState < boolean > (false)
const [pin, setPin] = useState < string > ('')
const [veryfy] = useMutation(VERIFY)
const verifyPin = () => {
if (!pin) {
alert('Please TYPE Valid PIN')
return;
}
//veryfy
setLoading(true);
veryfy({
variables: {
token: pin,
kind: 'PHONE'
}
}).then(({
data
}) => {
setLoading(false)
console.log(data);
if (data) {
props.navigation.navigate('Intro', {
token: token
});
}
}).catch((e) => {
setLoading(false)
console.log(e);
})
}
The below code is an example showing how you can use the Apollo middle-ware [1] and context [2] to add headers(auth) at runtime or testing.
First we create a middle-ware block, then an inner context block.
In the context block we can use the line below to add external parameters, this is to configure the request
const { isAuth, Authorization } = headers;
A boolean(Auth) can be set to allow a token to be embedded in a Authorization header, or an existing Authorization header can be passed in directly, this can be usefull for testing for example.
const getClient = () => {
// create link middleware see [1]
const authMiddleware = new ApolloLink((operation, forward) => {
// code block below assumes there exists an auth token in globals
// add headers with the client context [2]
operation.setContext(({ headers = {} }) => {
// auth header using global token as a bearer token
const authHeaders = {
Authorization: global.access_token
? `Bearer ${global.access_token}`
: "",
};
// here an Authorization header can be passed in thru the context,
// which can be useful, eg for testing
const { isAuth, Authorization } = headers;
// if we have an Auth.. header we can just add that and return
if (Authorization) {
return {
headers: { ...publicHeaders, ...{ Authorization } },
};
}
const header = isAuth
? { ...publicHeaders, ...authHeaders }
: publicHeaders;
return {
headers: header,
};
});
return forward(operation);
}); // end create middleware
// create the graphql endpoint [1]
const httpLink = new HttpLink({ uri: '/graphql' });
// create client with the middleware and return the client
// code block below assumes there exists a globalCache
return new ApolloClient({
cache: globalCache,
link: concat(authMiddleware, httpLink),
});
}
use
// add/configure the appropriate headers in the context block
// for the client
client
.mutate({
mutation: <some mutation>,
variables: <some variables>,
context: {
headers: {
isAuth: false, // or true for authenticated operation
},
},
})
.then((result) => ....)
.catch((err) => {
console.log(....);
});
use in a hook
const [runMutation, { data }] =
useMutation(<gql>, {
context: {
headers: { isAuth: true },
variables: <some vars>,
onCompleted: (data) => callback(data),
onError: (error) => console.error("Error ", error),
},
});
links
1 middleware
2 context

Why there is no data after the first login?

Dear vue and apollo users;
I am dealing with the first time install problem.
When I first launch the app, I don't get results.
I am using ApolloClient, InMemoryCache, HttpLink from "apollo-boost"
I store my userID and JWT in ApplicationSettings(local storage)
How to set token dynamically?
Vue.use(VueApollo);
const httpLink = new HttpLink({
uri: "https://sebapi.com/graphql"
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from ApplicationSettings if it exists
var tokenInAppSettings = ApplicationSettings.getString("token");
// return the headers to the context so HTTP link can read them
return {
headers: {
...headers,
authorization: tokenInAppSettings
? `Bearer ${tokenInAppSettings}`
: null
}
};
});
export const apolloClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
const apolloProvider = new VueApollo({
defaultClient: apolloClient
});
I have created a GitHub repo reproducing problem
and a youtube video of the problem
There is no error during login but after navigating to the list page for the first time I got following errors...
JS: [Vue warn]: Invalid prop: type check failed for prop "items". Expected Array, Object, got Undefined
JS: Error sending the query 'birds' ServerError: Response not successful: Received status code 400
IT SEEMS APOLLO DOES NOT HAVE userID during first query.
NOTE: You can easily clear user data by using yarn cl script
# debug app without HMR
yarn devn
# clear user data of app
yarn cl
Solution repo using vuex:
https://github.com/kaanguru/data-firstlogin/tree/user-in-vuex
Move userID into vue instance
+welcome.vue+
//const userId = ApplicationSettings.getNumber("userID");
// I have moved userID into vue.
export default {
data() {
return {
birds:[],
bird:{
id: null,
isim: "",
bilezik: ""
},
userId: ApplicationSettings.getNumber("userID")
};
},
apollo: {
birds: {
query: gql`
query myBirds($userId: ID!) {
birds(where: { user: $userId }) {
id
isim
bilezik
}
}
`,
variables() {
return {
userId: this.userId,
};
},
},
},
};

IBM IAM IamAuthenticator getToken is not a function

I'm trying to get a token to use IBM Watson Speech-to-Text in my app. Here's my code:
const { IamAuthenticator } = require('ibm-cloud-sdk-core');
const authenticator = new IamAuthenticator({
apikey: 'myApiKey',
});
authenticator.getToken(function (err, token) {
if (!token) {
console.log('error: ', err);
} else {
// use token
}
});
The error message is authenticator.getToken is not a function.
The documentation says:
string IBM.Cloud.SDK.Core.Authentication.Iam.IamAuthenticator.GetToken ( )
I've tried both getToken and GetToken. Same error message. The code isn't complicated, what am I doing wrong?
This is what worked for me with the latest ibm-watson node-sdk,
Install node-sdk with this command
npm install --save ibm-watson
Then, use this code snippet in your app.js or server.js node file to receive the IAM access token
const watson = require('ibm-watson/sdk');
const { IamAuthenticator } = require('ibm-watson/auth');
// to get an IAM Access Token
const authorization = new watson.AuthorizationV1({
authenticator: new IamAuthenticator({ apikey: '<apikey>' }),
url: ''
});
authorization.getToken(function (err, token) {
if (!token) {
console.log('error: ', err);
} else {
console.log('token: ', token);
}
});
You can also directly use the IamAuthenticator with Speech to Text
const fs = require('fs');
const SpeechToTextV1 = require('ibm-watson/speech-to-text/v1');
const { IamAuthenticator } = require('ibm-watson/auth');
const speechToText = new SpeechToTextV1({
authenticator: new IamAuthenticator({ apikey: '<apikey>' }),
url: 'https://stream.watsonplatform.net/speech-to-text/api/'
});
const params = {
// From file
audio: fs.createReadStream('./resources/speech.wav'),
contentType: 'audio/l16; rate=44100'
};
speechToText.recognize(params)
.then(response => {
console.log(JSON.stringify(response.result, null, 2));
})
.catch(err => {
console.log(err);
});
// or streaming
fs.createReadStream('./resources/speech.wav')
.pipe(speechToText.recognizeUsingWebSocket({ contentType: 'audio/l16; rate=44100' }))
.pipe(fs.createWriteStream('./transcription.txt'));
See my answer in your other post that might help. You use BearerTokenAuthenticator if you want to manage the token authentication process yourself.

React Native: Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'. at new ApolloError

I am trying to upload image from my react native app to graphql by using Apollo client with createUploadLink(). When I am trying to mutate data by passing a ReactNativeFile as a variable, then it says
"network request failed: Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'. at new ApolloError ".
This this the mutation which i am trying to use
mutation publishPost(
$content: String!
$LocationInput: LocationInput!
$InputPostAttachment: [InputPostAttachment!]
) {
publishPost(
content: $content
location: $LocationInput
attachments: $InputPostAttachment
) {
content
}
}
InputPostAttachment has type
type InputPostAttachment {
type: PostAttachmentType!
file: Upload!
}
Apollo client settings and i am using apollo-upload-client
const httpLink = createUploadLink({
uri: 'http://localhost:8000/graphql',
});
const authLink = setContext(async (headers: any) => {
const token = await getToken();
return {
...headers,
headers: {
authorization: token ? `Bearer ${token}` : null,
},
};
});
const link = authLink.concat(httpLink);
// create an inmemory cache instance for caching graphql data
const cache = new InMemoryCache();
// instantiate apollo client with apollo link instance and cache instance
export const client = new ApolloClient({
link,
cache,
});
File upload Function and i am using react-native-image-crop-picker for multi image selection
const [image, setimage] = useState([]);
const _pickImage = () => {
ImagePicker.openPicker({
includeBase64: true,
multiple: true,
}).then((images: any) => {
let imageData: any = [];
images.map((data: any) => {
const file = new ReactNativeFile({
uri: data.path,
name: data.filename,
type: data.mime,
});
imageData.push({
type: 'IMAGE',
file: file,
});
});
setimage(imageData);
console.log(images);
});
};
const handlePost = async () => {
const InputPostAttachment: any = [...image];
const LocationInput = {
place: place,
vicinity: vicinity,
province: province,
};
publishPost({variables: {content, LocationInput, InputPostAttachment}})
.then(({data}) => {
console.log(data);
props.navigation.navigate('Home');
})
.catch((err) => {
console.log('err happened');
console.log(err);
});
};
could someone please help me out from this?
In addition to the chrome debugger issue, this error also happens on the expo web.
To anyone uploading images on expo web (or react-native web), here's a working solution:
/** Load image from camera/roll. */
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
quality: 1,
});
if (result.cancelled) {
return;
}
/** web platform: blob. */
const convertBase64ToBlob = async (base64) => {
const response = await fetch(base64);
const blob = await response.blob();
return blob;
};
/** android/ios platform: ReactNativeFile.*/
const createReactNativeFile = (uri) => {
const file = new ReactNativeFile({
uri,
type: mime.lookup(uri) || 'image',
name: `file-${Date.now()}`,
});
return file;
};
/** Use blob for web, ReactNativeFile otherwise. */
const file = Platform.OS === 'web'
? await convertBase64ToBlob(result.uri)
: createReactNativeFile(result.uri);
/** Upload image with apollo. */
mutate({ variables: { file } });
On the web platform, ImagePicker returns a base64 value instead of a file path. This problem doesn't happen if the platform is Android or iOS, as ImagePicker returns a file path, which is expected by apollo-upload-client.
The solution is to detect if the URI is base64 (which happens when the platform is "web") and convert it to a blob.
My apollo-client was configured using apollo-boost and i was using chrome debugger to intercept the network was causing me this issue.
To be more specific I was using the below code to get the network requests sent by my app in the chrome debugger
global.XMLHttpRequest =
global.originalXMLHttpRequest || global.XMLHttpRequest;
global.FormData = global.originalFormData || global.FormData;
if (window.FETCH_SUPPORT) {
window.FETCH_SUPPORT.blob = false;
} else {
global.Blob = global.originalBlob || global.Blob;
global.FileReader = global.originalFileReader || global.FileReader;
}
apollo-upload-client wont send the data in multipart data if we are using chrome debugger. We will face network issue.This issue has the answer. or I had not removed apollo-boost and some part of my app was using it that was also a issue.