React nativ, aws-amplify storage, getting aws.cognito.identity-id - reactjs

i am trying to get aws.cognito.identity-id with React-Native. After successeful sign-in i am getting CognitoUser, but storage variable is equal to [Function MemoryStorage], however with React in my web browser storage has some values. Code in React and React native exactly same.
Browser output:
...
storage: Storage
CognitoIdentityId-eu-central-1:...: "..."
CognitoIdentityServiceProvider.....LastAuthUser: "..."
CognitoIdentityServiceProvider.........accessToken: "..."
CognitoIdentityServiceProvider........clockDrift: "2"
...
Android device output:
...
"storage": [Function MemoryStorage],
...
Code
Amplify.configure({
...awsmobile
});
const client = new AWSAppSyncClient({
url: awsmobile.aws_appsync_graphqlEndpoint,
region: awsmobile.aws_appsync_region,
auth: {
type: AUTH_TYPE.AWS_IAM,
credentials: () => Auth.currentCredentials()
},
});
Auth.signIn(
'myemail#gmail.com',
'pass'
)
// .then(user => console.log('user',user))
.then(user => signInSuccess(user));
function getValueFromKey(myObject, string) {
const key = Object.keys(myObject).filter(k => k.includes(string));
return key.length ? myObject[key] : "";
}
function signInSuccess(user) {
console.log('another', user);
console.log(getValueFromKey(user.storage, 'aws.cognito.identity-id'))
}
export default class App extends React.Component {
render() {
return (
<Text>nice</Text>
);
}
}

Related

TradingView Chart Library not working on production

I've implemented the TradingView charting library on my react project following the documentation provided.
Copy charting_library folder from
https://github.com/tradingview/charting_library/ to /public and to
/src folders. Copy datafeeds folder from
https://github.com/tradingview/charting_library/ to /public.
exactly as mentioned in the documentation , when i run yarn start it's working and showing however , when I build and try to serve it using nginx .
I get an error saying .
TypeError: Cannot read properties of undefined (reading
'UDFCompatibleDatafeed').
import * as React from "react";
import "./index.css";
import {
widget,
ChartingLibraryWidgetOptions,
IChartingLibraryWidget
} from "../../../charting_library";
import { useMarket, USE_MARKETS } from "../../utils/markets";
import * as saveLoadAdapter from "./saveLoadAdapter";
import { flatten } from "../../utils/utils";
import { BONFIDA_DATA_FEED } from "../../utils/bonfidaConnector";
import {} from "../../../charting_library";
export interface ChartContainerProps {
symbol: ChartingLibraryWidgetOptions["symbol"];
interval: ChartingLibraryWidgetOptions["interval"];
auto_save_delay: ChartingLibraryWidgetOptions["auto_save_delay"];
// BEWARE: no trailing slash is expected in feed URL
// datafeed: any;
datafeedUrl: string;
libraryPath: ChartingLibraryWidgetOptions["library_path"];
chartsStorageUrl: ChartingLibraryWidgetOptions["charts_storage_url"];
chartsStorageApiVersion: ChartingLibraryWidgetOptions["charts_storage_api_version"];
clientId: ChartingLibraryWidgetOptions["client_id"];
userId: ChartingLibraryWidgetOptions["user_id"];
fullscreen: ChartingLibraryWidgetOptions["fullscreen"];
autosize: ChartingLibraryWidgetOptions["autosize"];
studiesOverrides: ChartingLibraryWidgetOptions["studies_overrides"];
containerId: ChartingLibraryWidgetOptions["container_id"];
theme: string;
}
export interface ChartContainerState {}
export const TVChartContainer = () => {
// let datafeed = useTvDataFeed();
const defaultProps: ChartContainerProps = {
symbol: "BTC/USDC",
// #ts-ignore
interval: "60",
auto_save_delay: 5,
theme: "Dark",
containerId: "tv_chart_container",
// datafeed: datafeed,
libraryPath: "/charting_library/",
chartsStorageApiVersion: "1.1",
clientId: "tradingview.com",
userId: "public_user_id",
fullscreen: false,
autosize: true,
datafeedUrl: BONFIDA_DATA_FEED,
studiesOverrides: {}
};
const tvWidgetRef = React.useRef<IChartingLibraryWidget | null>(null);
const { market } = useMarket();
const chartProperties = JSON.parse(
localStorage.getItem("chartproperties") || "{}"
);
React.useEffect(() => {
const savedProperties = flatten(chartProperties, {
restrictTo: ["scalesProperties", "paneProperties", "tradingProperties"]
});
let newWindow :any = window ;
console.log("defaultProps.datafeedUrl", newWindow.Datafeeds);
const widgetOptions: ChartingLibraryWidgetOptions = {
symbol:
USE_MARKETS.find(
(m) => m.address.toBase58() === market?.publicKey.toBase58()
)?.name || "SRM/USDC",
// BEWARE: no trailing slash is expected in feed URL
// tslint:disable-next-line:no-any
// #ts-ignore
// datafeed: datafeed,
// #ts-ignore
datafeed:new (window as any).Datafeeds.UDFCompatibleDatafeed(
defaultProps.datafeedUrl,
),
interval:
defaultProps.interval as ChartingLibraryWidgetOptions["interval"],
container_id:
defaultProps.containerId as ChartingLibraryWidgetOptions["container_id"],
library_path: defaultProps.libraryPath as string,
auto_save_delay: 5,
locale: "en",
disabled_features: ["use_localstorage_for_settings"],
enabled_features: ["study_templates"],
load_last_chart: true,
client_id: defaultProps.clientId,
user_id: defaultProps.userId,
fullscreen: defaultProps.fullscreen,
autosize: defaultProps.autosize,
studies_overrides: defaultProps.studiesOverrides,
theme: defaultProps.theme === "Dark" ? "Dark" : "Light",
overrides: {
...savedProperties,
"mainSeriesProperties.candleStyle.upColor": "#41C77A",
"mainSeriesProperties.candleStyle.downColor": "#F23B69",
"mainSeriesProperties.candleStyle.borderUpColor": "#41C77A",
"mainSeriesProperties.candleStyle.borderDownColor": "#F23B69",
"mainSeriesProperties.candleStyle.wickUpColor": "#41C77A",
"mainSeriesProperties.candleStyle.wickDownColor": "#F23B69",
"background": "#141424 ",
"backgroundColor" : "#141424 "
},
// #ts-ignore
save_load_adapter: saveLoadAdapter,
settings_adapter: {
initialSettings: {
"trading.orderPanelSettingsBroker": JSON.stringify({
showRelativePriceControl: false,
showCurrencyRiskInQty: false,
showPercentRiskInQty: false,
showBracketsInCurrency: false,
showBracketsInPercent: false
}),
// "proterty"
"trading.chart.proterty":
localStorage.getItem("trading.chart.proterty") ||
JSON.stringify({
hideFloatingPanel: 1
}),
"chart.favoriteDrawings":
localStorage.getItem("chart.favoriteDrawings") ||
JSON.stringify([]),
"chart.favoriteDrawingsPosition":
localStorage.getItem("chart.favoriteDrawingsPosition") ||
JSON.stringify({})
},
setValue: (key, value) => {
localStorage.setItem(key, value);
},
removeValue: (key) => {
localStorage.removeItem(key);
}
}
};
const tvWidget = new widget(widgetOptions);
tvWidget.onChartReady(() => {
tvWidgetRef.current = tvWidget;
tvWidget
// #ts-ignore
.subscribe("onAutoSaveNeeded", () => tvWidget.saveChartToServer());
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [market, tvWidgetRef.current]);
return <div id={defaultProps.containerId} className={"TVChartContainer"} />;
};
function useTvDataFeed() {
throw new Error("Function not implemented.");
}
ps: i've tried to implement this project : https://github.com/project-serum/serum-dex-ui

social login (nextauth) isn't working with after i add autoprefixer

does anyone know what this means, and how i can debug it - i've tried react dev tools - and the states and everything disappear as soon as this message pops up:
Server Error
TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined.
This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack
<unknown>
file:///home/abda_react/abdn2/node_modules/next-auth/server/lib/providers.js (29:5)
Array.find
<anonymous>
parseProviders
file:///home/abda_react/abdn2/node_modules/next-auth/server/lib/providers.js (28:30)
NextAuthHandler
file:///home/abda_react/abdn2/node_modules/next-auth/server/index.js (88:30)
<unknown>
file:///home/abda_react/abdn2/node_modules/next-auth/server/index.js (251:38)
Object.apiResolver
file:///home/abda_react/abdn2/node_modules/next/dist/server/api-utils.js (101:15)
runMicrotasks
<anonymous>
processTicksAndRejections
node:internal/process/task_queues (96:5)
async DevServer.handleApiRequest
file:///home/abda_react/abdn2/node_modules/next/dist/server/next-server.js (770:9)
async Object.fn
file:///home/abda_react/abdn2/node_modules/next/dist/server/next-server.js (661:37)
my nextauth config file:
import NextAuth from "next-auth"
import EmailProvider from 'next-auth/providers/email';
import GoogleProvider from "next-auth/providers/google";
export default NextAuth({
// Configure one or more authentication providers
providers: [
,EmailProvider({
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
})
,GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
// ...add more providers here
],
jwt: {
encryption: true,
},
secret: process.env.secret,
//https://www.youtube.com/watch?v=QK24lEvRTI8
callback: {
// async jwt(token, account) {
// if (account?.accessToken) {
// token.accessToken = account.accessToken;
// }
// return token;
// },
// redirect: async (url, _baseUrl) => {
// if (url === '/') {
// return Promise.resolve('/index');
// }
// return Promise.resolve('/index');
// }
},
pages: {
// signIn: '/auth/signin',
// signOut: '/auth/signout',
// error: '/auth/error', // Error code passed in query string as ?error=
// verifyRequest: '/auth/verify-request', // (used for check email message)
// newUser: '/auth/new-user' // New users will be directed here on first sign in (leave the property out if not of interest)
}
})
// https://console.cloud.google.com/projectselector2/apis/credentials?authuser=1&pli=1&supportedpurview=project
//All requests to /api/auth/* (signIn, callback, signOut, etc.) will automatically be handled by NextAuth.js.
could it be something that's wrongly configured?? but i dont understand why it would work before i installed auto prefixer...
here is the providers file(i did not write a single code of it):
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = parseProviders;
var _merge = require("../../lib/merge");
function parseProviders(params) {
const {
base,
providerId
} = params;
const providers = params.providers.map(({
options,
...rest
}) => {
var _userOptions$id, _userOptions$id2;
const defaultOptions = normalizeProvider(rest);
const userOptions = normalizeProvider(options);
return (0, _merge.merge)(defaultOptions, { ...userOptions,
signinUrl: `${base}/signin/${(_userOptions$id = userOptions === null || userOptions === void 0 ? void 0 : userOptions.id) !== null && _userOptions$id !== void 0 ? _userOptions$id : rest.id}`,
callbackUrl: `${base}/callback/${(_userOptions$id2 = userOptions === null || userOptions === void 0 ? void 0 : userOptions.id) !== null && _userOptions$id2 !== void 0 ? _userOptions$id2 : rest.id}`
});
});
const provider = providers.find(({
id
}) => id === providerId);
return {
providers,
provider
};
}
function normalizeProvider(provider) {
var _provider$version;
if (!provider) return;
const normalizedProvider = Object.entries(provider).reduce((acc, [key, value]) => {
if (["authorization", "token", "userinfo"].includes(key) && typeof value === "string") {
var _url$searchParams;
const url = new URL(value);
acc[key] = {
url: `${url.origin}${url.pathname}`,
params: Object.fromEntries((_url$searchParams = url.searchParams) !== null && _url$searchParams !== void 0 ? _url$searchParams : [])
};
} else {
acc[key] = value;
}
return acc;
}, {});
if (provider.type === "oauth" && !((_provider$version = provider.version) !== null && _provider$version !== void 0 && _provider$version.startsWith("1.")) && !provider.checks) {
normalizedProvider.checks = ["state"];
}
return normalizedProvider;
}
so..from what i am guessing, there is no property id in there...but i have no idea why that would change after installing autoprefixer, and also i have no idea how to even consider adding id into this.
update
changed the providers variable to see maybe it's just google...and it seems i have another issue which i think might be related. here is the error:
./pages/api/auth/[...nextauth].js:3:0
Module not found: Package path ./providers is not exported from package /home/abda_react/abdn2/node_modules/next-auth (see exports field in /home/abda_react/abdn2/node_modules/next-auth/package.json)
1 | import NextAuth from "next-auth"
2 | import EmailProvider from 'next-auth/providers/email';
> 3 | import Providers from "next-auth/providers";
4 |
5 | export default NextAuth({
6 | // Configure one or more authentication providers
Import trace for requested module:
https://nextjs.org/docs/messages/module-not-found
here is what i changed:
import NextAuth from "next-auth"
import EmailProvider from 'next-auth/providers/email';
import Providers from "next-auth/providers";
export default NextAuth({
// Configure one or more authentication providers
providers: [
// ,EmailProvider({
// server: process.env.EMAIL_SERVER,
// from: process.env.EMAIL_FROM,
// })
,Providers.Google({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
// ...add more providers here
package.json:
"exports": {
".": "./index.js",
"./jwt": "./jwt/index.js",
"./react": "./react/index.js",
"./providers/*": "./providers/*.js"
},
ok two things:
my email provider credentials were placeholders - that's not good.
your signin page needs to be set
for completion, here's what i did:
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google";
export default NextAuth({
// Configure one or more authentication providers
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
]
,callback: {
async jwt(token, account) {
if (account?.accessToken) {
token.accessToken = account.accessToken;
}
return token;
},
redirect: async (url, _baseUrl) => {
if (url === '/') {
return Promise.resolve('/index');
}
return Promise.resolve('/index');
}
,pages: {
signIn: '/index',
signOut: '/index',
}
,debug: false
}
})
even though i still cant import all providers - it works, so good enough for now
but again...not sure why it worked before autoprefix...

Default dynamic route in Next.js

Next.js enables us to define dynamic routes in our apps using the brackets [param]. It allows us to design URL in such a way that for example language is passed as parameter. When no route matches the user is redirected to error page.
The idea is simple and documentation abut dynamic routes in Next.js is rather limited. Does anybody know if it's possible to assign a default value to dynamic route parameter?
There are docs pages about i18n routing and redirects and special support for locale parameters (which I have not used personally).
In a more general sense, it sounds like what you want is optional catch all routes.
You can define a file in your foo directory with the name [[...slug]].js. The params which correspond to a path like /foo/us/en is { slug: ["us", "en"] } where each segment of the path becomes an element of the slug array.
You can use getStaticPaths to generate all of the known country/language pairs. Setting fallback: true allows for the user to enter another combo and not get a 404.
export const getStaticPaths = async () => {
return {
paths: [
{ params: { slug: ["us", "en"] } },
{ params: { slug: ["us", "es"] } },
{ params: { slug: ["ca", "en"] } },
{ params: { slug: ["ca", "fr"] } },
/*...*/
],
fallback: true, // allows unknown
};
};
As far as redirection, it depends on whether you want an actual redirect such that typing in /foo leads to /foo/us/en or if those are two separate pages which show the same content. I'm going to assume that we want an actual redirect.
You'll convert from slug to props in your getStaticProps function. This is also where you implement your redirects. I'm going to assume that you have (or can create) some utility functions like isValidCountry(country) and getDefaultLanguage(country)
export const getStaticProps = async ( context ) => {
const [country, language] = context.params?.slug ?? [];
// if there is no country, go to us/en
if (!country || !isValidCountry(country)) {
return {
redirect: {
statusCode: 301, // permanent redirect
destination: "/foo/us/en",
},
};
}
// if there is no language, go to the default for that country
if (!language || !isValidLanguage(language, country)) {
return {
redirect: {
statusCode: 301, // permanent redirect
destination: `/foo/${country}/${getDefaultLanguage(country)}`,
},
};
}
// typical case, return country and language as props
return {
props: {
country,
language,
},
};
};
There are things that you can do in the component itself with useRouter and isFallback, but I'm not sure if it's needed. In dev mode at least I'm getting proper redirects.
/foo/ca/en - ok
/foo/ca/fr - ok
/foo/ca/xx - redirects to /foo/ca/en
/foo/ca - redirects to /foo/ca/en
/foo - redirects to /foo/us/en
Complete code with TypeScript types:
import { GetStaticPaths, GetStaticProps } from "next";
export interface Props {
country: string;
language: string;
}
export default function Page({ country, language }: Props) {
return (
<div>
<h1>
{country} - {language}
</h1>
</div>
);
}
const pairs = [
["us", "en"],
["us", "es"],
["ca", "en"],
["ca", "fr"],
];
const isValidCountry = (c: string) => pairs.some(([cc]) => cc === c);
const isValidLanguage = (l: string, c: string) =>
pairs.some(([cc, ll]) => cc === c && ll === l);
const getDefaultLanguage = (c: string) =>
pairs.find(([cc]) => cc === c)?.[1] ?? "en";
export const getStaticProps: GetStaticProps<Props, { slug: string[] }> = async (
context
) => {
const [country, language] = context.params?.slug ?? [];
// if there is no country, go to us/en
if (!country || !isValidCountry(country)) {
return {
redirect: {
statusCode: 301, // permanent redirect
destination: "/foo/us/en",
},
};
}
// if there is no language, go to the default for that country
if (!language || !isValidLanguage(language, country)) {
return {
redirect: {
statusCode: 301, // permanent redirect
destination: `/foo/${country}/${getDefaultLanguage(country)}`,
},
};
}
// typical case, return country and language as props
return {
props: {
country,
language,
},
};
};
export const getStaticPaths: GetStaticPaths<{ slug: string[] }> = async () => {
return {
paths: pairs.map((slug) => ({
params: { slug },
})),
fallback: true, // allows unknown
};
};

React Native - How to initialize OneSignal in a stateless function component?

I've read OneSignal installation here: https://documentation.onesignal.com/docs/react-native-sdk-setup#step-5---initialize-the-onesignal-sdk. The documentation is written in a component class style.
How to add the OneSignal in the stateless function component on React Native app?
I've tried using useEffect but OneSignal still can't detect my app.
Thanks.
Enjoy
import OneSignal from 'react-native-onesignal';
const SplashScreen = () => {
useEffect(() => {
OneSignal.setLogLevel(6, 0);
OneSignal.init('Your-id-app', {
kOSSettingsKeyAutoPrompt: false,
kOSSettingsKeyInAppLaunchURL: false,
kOSSettingsKeyInFocusDisplayOption: 2,
});
OneSignal.inFocusDisplaying(2);
OneSignal.addEventListener('received', onReceived);
OneSignal.addEventListener('opened', onOpened);
OneSignal.addEventListener('ids', onIds);
return () => {
OneSignal.removeEventListener('received', onReceived);
OneSignal.removeEventListener('opened', onOpened);
OneSignal.removeEventListener('ids', onIds);
};
}, []);
const onReceived = (notification) => {
console.log('Notification received: ', notification);
};
const onOpened = (openResult) => {
console.log('Message: ', openResult.notification.payload.body);
console.log('Data: ', openResult.notification.payload.additionalData);
console.log('isActive: ', openResult.notification.isAppInFocus);
console.log('openResult: ', openResult);
};
const onIds = (device) => {
console.log('Device info: ', device);
};
return (
...
);
};
I got it worked by added these lines on App.js:
import OneSignal from 'react-native-onesignal';
...
...
const App = () => {
...
onIds = (device) => {
if (state.playerId) {
OneSignal.removeEventListener('ids', onIds);
return;
} else {
setState({ ...state, playerId: device.userId });
console.log('Device info: ', state.playerId);
}
};
OneSignal.addEventListener('ids', onIds);
...
}
And in index.js:
import OneSignal from 'react-native-onesignal'; // Import package from node modules
OneSignal.setLogLevel(6, 0);
// Replace 'YOUR_ONESIGNAL_APP_ID' with your OneSignal App ID.
OneSignal.init(YOUR_ONESIGNAL_APP_ID, {
kOSSettingsKeyAutoPrompt: false,
kOSSettingsKeyInAppLaunchURL: false,
kOSSettingsKeyInFocusDisplayOption: 2
});
OneSignal.inFocusDisplaying(2); // Controls what should happen if a notification is received while the app is open. 2 means that the notification will go directly to the device's notification center.

Using hello.js with React.js

I'd like to understand how to make Hello.js work with React.js , especially the custom event handler hello.on
As I'm new to React.js, I don't understand how to bind non React events into the app flow.
I tried putting the event handler in the componentDidMount handler
handleClick(){
hello('twitter').login();
}
componentDidMount(){
hello.on('auth.login', function(auth) {
// Call user information, for the given network
hello(auth.network).api('/me').then(function(r) {
console.log(r);
});
});
hello.init({
'twitter' : 'J1jqqO50tcLtLx8Js0VDitjZW'
},
{
redirect_uri:'/',
oauth_proxy: 'https://auth-server.herokuapp.com/proxy'
});
}
thanks
And 3 years later:
You need a class for authentication, for example:
import * as React from "react";
import * as hello from "hellojs";
import { Event } from "../interfaces/Event";
export class Authentication extends React.Component<{}, { sendEvent: boolean }> {
constructor(public props, public context) {
super(props, context);
this.state = {
sendEvent: true
};
}
public login(network) {
hello.init({
aad: {
name: "Azure Active Directory",
oauth: {
version: 2,
auth: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
grant: "https://login.microsoftonline.com/common/oauth2/v2.0/token"
},
// Authorization scopes
scope: {
// you can add as many scopes to the mapping as you want here
profile: "user.read",
offline_access: ""
},
scope_delim: " ",
login: p => {
if (p.qs.response_type === "code") {
// Let's set this to an offline access to return a refresh_token
p.qs.access_type = "offline_access";
}
},
base: "https://www.graph.microsoft.com/v1.0/",
get: {
me: "me"
},
xhr: p => {
if (p.method === "post" || p.method === "put") {
JSON.parse(p);
} else if (p.method === "patch") {
hello.utils.extend(p.query, p.data);
p.data = null;
}
return true;
},
// Don't even try submitting via form.
// This means no POST operations in <=IE9
form: false
}
});
hello.init(
{
aad: "ClientID"
},
{
redirect_uri: "YOUR REDIRECT_URI",
//redirect_uri: 'https://localhost:4321/temp/workbench.html',
scope: "user.read"
}
);
// By defining response type to code, the OAuth flow that will return a refresh token to be used to refresh the access token
// However this will require the oauth_proxy server
hello(network)
.login({ display: "none" })
.then(
authInfo => {
console.log(authInfo);
localStorage.setItem("logged", authInfo.authResponse.access_token);
},
e => {
console.error("Signin error: " + e.error.message);
}
);
}
//when the component is mounted you check the localstorage
//logged ==> undefined you call login and save a token in localstorage
//logged ==> with a token -> setEvent call a function that use graph api
public componentDidMount() {
let logged = localStorage["logged"];
if (logged === undefined) this.login("aad");
else {
if (this.state.sendEvent) {
this.props.setEvent(null);
this.props.setEvent(Event.GET_ALL_USERS);
}
}
}
public render() {
return null;
}
}
the file name is auth.tsx and you can call this class in the main react class:
export class mainClass extends React.Component{
......
......
private getEvent = (event) => {
this.setState({ event: event });
//HERE YOU recive the event when auth is ready
}
public render(){
<Authentication setEvent={this.getEvent} />
}
}

Resources