I am using AWS Amplify in my React Native app as instructed here: https://docs.amplify.aws/ui/auth/authenticator/q/framework/react-native/#using-the-authenticator-component
It is working, more or less. But when I log in there is a box saying Hello with a Sign Out button added to the project. I can get rid of this by setting hideDefault={true} but then if I log out there is no login/signup screen. My code is below, thank you for any help.
import { StyleSheet, Text, Button,View,Platform,StatusBar,Image, TouchableWithoutFeedback, SafeAreaView } from 'react-native';
import {useState} from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { useNavigationContainerRef } from '#react-navigation/native';
import Ionicons from 'react-native-vector-icons/Ionicons';
// Screens
import Browsescreen from './screens/Browsescreen';
// AWS
import { Authenticator } from 'aws-amplify-react-native/dist/Auth';
const Tab = createBottomTabNavigator();
function App() {
const navigationRef = useNavigationContainerRef();
const [showLoggedInPage, setLoggedInPage] = useState(false);
const loggedInPage = showLoggedInPage ? (
<SafeAreaView style={styles.container}>
<StatusBar style="auto" />
<View>
[REMOVED]
</View>
<NavigationContainer ref={navigationRef}>
<Tab.Navigator>
[REMOVED]
</Tab.Navigator>
</NavigationContainer>
</SafeAreaView>
) : null;
return (
<Authenticator
onStateChange={(authState) => {
console.log(authState)
if (authState == "signedIn") {
setLoggedInPage(true);
} else {
setLoggedInPage(false);
}
}
}
hideDefault={false}
>
{loggedInPage}
</Authenticator>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ddd',
},
});
export default App;
I am new to this, please make it as simple as possible and provide sample if possible. Thank you!
Based on this documentation, if you are using the HOC component withAuthenticator.
export default withAuthenticator(App, {
// Render a sign out button once logged in
includeGreetings: true,
});
The sign-out button is shown when "includeGreetings" is set to "true". Changing it to "false" will hide the sign-out button.
Related
I am following the instructions at: https://docs.amplify.aws/ui/auth/authenticator/q/framework/react-native/#using-the-authenticator-component
I can get things working, mostly. I can access authState inside of onStateChange as well, but I cannot figure out how to access authData so I can get things like username, etc.
Could someone please provide an example of how this is done?
Here is my code now:
import { StyleSheet, Text, Button,View,Platform,StatusBar,Image, TouchableWithoutFeedback, SafeAreaView } from 'react-native';
import {useState} from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { useNavigationContainerRef } from '#react-navigation/native';
import Ionicons from 'react-native-vector-icons/Ionicons';
// Screens
import Browsescreen from './screens/Browsescreen';
// AWS
import { Authenticator } from 'aws-amplify-react-native/dist/Auth';
const Tab = createBottomTabNavigator();
function App() {
const navigationRef = useNavigationContainerRef();
const [showLoggedInPage, setLoggedInPage] = useState(false);
const loggedInPage = showLoggedInPage ? (
<SafeAreaView style={styles.container}>
<StatusBar style="auto" />
<View>
[REMOVED]
</View>
<NavigationContainer ref={navigationRef}>
<Tab.Navigator>
[REMOVED]
</Tab.Navigator>
</NavigationContainer>
</SafeAreaView>
) : null;
return (
<Authenticator
onStateChange={(authState) => {
console.log(authState)
if (authState == "signedIn") {
setLoggedInPage(true);
} else {
setLoggedInPage(false);
}
}
}
hideDefault={false}
>
{loggedInPage}
</Authenticator>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ddd',
},
});
export default App;
Please remember I am new so simple answer with sample if possible please. Thank you.
On my Static next.js website, I have a component <GoogleAnalytics /> holding my Google Analytics snippet.
I want this snippet to not be called on my localhost:3000
In my _app.js I have the following Tenary Operator but it is still showing the code of the component on localhost:3000.
import { useState, useEffect } from "react";
import GoogleAnalytics from "../components/GoogleAnalytics";
function MyApp({ Component, pageProps }) {
const [host, setHost] = useState();
useEffect(() => {
setHost(window.location.host);
}, []);
return (
<>
{host === "localhost:3000" ? <></> : <GoogleAnalytics />}
<Component {...pageProps} />
</>
);
}
export default MyApp;
Any idea what I'm doing wrong?
So i set up mobx and the files show no error in visual studio code and the react client app compile just fine and it shows the list of Departments but there is also a button thats not working its set up all fine and the onClick event is all fine but it doesnt work I had problems with mobx because its greater than version 6 or idk its version so i had to add the construvtor to display the list
Department store
import {observable, action, makeObservable} from 'mobx';
import { createContext } from 'react';
import agent from '../api/agent';
import { IDepartment } from '../models/department';
class DepartmentStore {
#observable departments: IDepartment[] = [];
#observable selectedDepartment: IDepartment | undefined;
#observable loadingInitial = false;
#observable editMode =false;
constructor() {
// Just call it here
makeObservable(this);
}
#action loadDepartments= () => {
this.loadingInitial = true;
agent.Departments.list()
.then(departments => {
departments.forEach((department) => {
this.departments.push(department);
})
}).finally(() => this.loadingInitial = false);
};
#action selectDepartment = (id: string) => {
this.selectedDepartment = this.departments.find(d => d.id === id);
this.editMode = false;
}
}
export default createContext(new DepartmentStore());
so everything here shows no error below ill display the DepartmentList code where it contains the button thats now functioning
import { observer } from "mobx-react-lite";
import React, { SyntheticEvent, useContext } from "react";
import { Item, Button, Segment } from "semantic-ui-react";
import { IDepartment } from "../../../app/models/department";
import DepartmentStore from "../../../app/stores/departmentStore";
interface IProps {
deleteDepartment: (event: SyntheticEvent<HTMLButtonElement>,id: string) => void;
submitting: boolean;
target: string;
}
export const DepartmentList: React.FC<IProps> = ({
deleteDepartment,
submitting,
target
}) => {
const departmentStore = useContext(DepartmentStore);
const {departments, selectDepartment} = departmentStore;
return (
<Segment clearing>
<Item.Group divided>
{departments.map((department) => (
<Item key={department.id}>
<Item.Content style={{ display: "flex" }}>
<Item.Header style={{ width: "100%", marginTop: "1em" }}>
{department.name}
</Item.Header>
<Item.Extra>
<Button
name={department.id}
loading={target === department.id && submitting}
onClick={(e) => deleteDepartment(e, department.id)}
content="Delete"
color="red"
floated="right"
/>
<Button
onClick={() => selectDepartment(department.id)}
content="View"
color="blue"
floated="right"
/>
</Item.Extra>
</Item.Content>
</Item>
))}
</Item.Group>
</Segment>
);
};
export default observer(DepartmentList)
;
I am currently making an application using react-native, expo, and AWS. I use Cognito for authentification and I have it set up such that I can successfully mutate and query a database in DynamoDB.
I am now attempting to write code such that I can store the pictures for the users of my application in S3 and store the path to that picture in DynamoDB. However, upon running the following:
const result2 = await Storage.get('test.txt')
console.log(result2)
The log gives me a link that takes me to what appears to be an xml file that reads:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>InvalidToken</Code>
<Message>
The provided token is malformed or otherwise invalid.
</Message>
<Token-0>
AgoJb3JpZ2luX2VjEA4aCXVzLWVhc3QtMiJIMEYCIQD/DyNL3qxQ3XrXBXsOlH2ojEks6sfdN9Vp7rPT5K9JFQIhAI2lEAmu6ivQIQKNtAo1VqFuZgdld5S/DrfcElNsVDo/Kq8FCOf//////////wEQABoMODM3Njc2NjA0ODkyIgwj9ikFX4w7POTaQlEqgwXkzZRq7kCqo8W0YaAD6fT7sJ4nok4nxzBO58frPZ4a1nSCESuwq/VShJZMQAMDkDPKci4vV v aJMhPOJXvtRjkoIQ5lGaCQAqYMXDeU/RFOJosmekNZ 0vZGu/X9KWfcNFhJaz7WW5FDl3N3u BGQdBzUjNhCrl01HMpKyL5F0HFB1mq4l H9d FyvPD4 LStyNOXYkGKf7X34hEZdccRkbjDyzfG4hBmv64JGiJfgh5 dD6IlNdNsqkw7N1Uw26Q7mf3erhOrwJwLIDyYC77LW3HU9uLqxQBH0MiTxJBcWW47BT4xENuSHZ136zRazgjHYcin Sr1NyCKwI4e2BbJ//Fudi Jnjf/QDPgYmSrpOO/0p5YGejpPYoZ6cqFy7V8xuI82YK/CZTc5hCOBMvo7NyPa2lsGkDXcfh IknmVEH5OXHhM0FPGM/U6L0ikBUYJgqqiVqByxdrUyYt F6FxapyCKgWcBCXwQUq28KoFvhIqXFbc5hlkGxFdUvIK2WWtMpDntcvU6hgivXoRRGKh880vkQV6bQsF3AaniH/El0EcI5jGF5aiciNZo9wNuMKMsA8w7bpT hBDETHeGOd3lenGNvgazdwWKnnhqN3QqwaSPFjd0Q41wNYOH8ySmP0S0/UbYCTIwRDx1o4FX6UI2THnS8nOvbtEG32QHDpqY3gpL00tCLGO4S9BFtkIC2TbhvX7jfF3bAbfvjEVOFhENT0K v OYq02Ig4dlMa4DdnPexEmy666R8Pbf 7fTCP2wzWDXjfxJjxkKx8gfsTmUOgDgUPb2p8azxSXzJr1Rg5 zhhX0DuVepg5z66HQS23RwAhIkOrXEzi95nPbd9NAOMNPw0OwFOrMB4lBUn04vbQAqDiKOe91AZR64351xwrn0jp5zZ YwumK9Tk/3rY/ N2ibYoiHdfOM3Wg4Ucm2 qCDWtJIkbvCAXlhjrpUZLmV6dJATJ417OzlUlJfsK04y7K8uNrGSFwbWYw3/gblaggupxQc7TrpmhKCIXHVIdZZmawMH5vfULkhHQL/FiQKdt13znIZ/hHGs1jc3cC9Z NmhMIXtufNlIGvKmWzNCq8LegxNzoZtlXqVWM=
</Token-0>
<RequestId>5186B48D259D1B01</RequestId>
<HostId>
RJptwOZEArdnFf7Zmk7Od8oFWh68GeR8ey/O13M39JuVxSScYyKXVVVsXwa+37Wus1M/DHttry8=
</HostId>
</Error>
For reference, the rest of my App.js file reads:
/*
General
*/
import React from 'react';
import { Platform, Component, StyleSheet, Text, View, TextInput, Button, TouchableOpacity } from 'react-native';
/*
Amplify
*/
import Amplify from '#aws-amplify/core'
import config from './src/aws-exports'
Amplify.configure({
...config,
Analytics: { //Needed to disable possible promise reject error from analytics
disabled: true
}
});
/*
Authentification
*/
import Auth from '#aws-amplify/auth'
import { withAuthenticator } from 'aws-amplify-react-native'
/*
Database
*/
import API, { graphqlOperation } from '#aws-amplify/api'
import {Storage} from 'aws-amplify'
import * as queries from './src/graphql/queries';
import * as mutations from './src/graphql/mutations';
import * as subscriptions from './src/graphql/subscriptions';
import {v4 as uuid} from 'uuid';
class App extends React.Component {
state = {
name: "",
User: []
}
onChangeText = (key, val) => {
this.setState({ [key]: val })
}
addUser = async event => {
const { name, User } = this.state
event.preventDefault()
const information = {
username: name,
}
const result = await API.graphql(graphqlOperation(mutations.createUser, {input: information}))
const newUser = result.data.createUser
const updatedUser = [newUser, ...User]
this.setState({ User: updatedUser, name: "" })
/*
Adding Files Test
*/
const result2 = await Storage.get('test.txt')
console.log(result2)
}
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
value={this.state.name}
onChangeText={val => this.onChangeText("name", val)}
placeholder='Add a User'
/>
<TouchableOpacity onPress={this.addUser} style={styles.buttonContainer}>
<Text style={styles.buttonText}>Add +</Text>
</TouchableOpacity>
</View>
);
}
}
export default withAuthenticator(App, { includeGreetings: true })
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
paddingHorizontal: 10,
paddingTop: 50
},
input: {
height: 50,
borderBottomWidth: 2,
borderBottomColor: "blue",
marginVertical: 10
},
buttonContainer: {
backgroundColor: "#34495e",
marginTop: 10,
marginBottom: 10,
padding: 10,
borderRadius: 5,
alignItems: "center"
},
buttonText: {
color: "#fff",
fontSize: 24
}
})
What would this error mean? Am I simply giving get() the wrong type of input? I do have a file called "test.txt" in the top level of my S3.
So I'm trying to get started with ionic 2 from ionic 1 and need some guidance on how to set up authentication in my project. Specifically I'm using firebase and angularfire2.
As a general approach should I either:
a. Check for session/localStorage on app.ts and set the rootPage to login if unauthenticated? Using this method if I log the user out and set the nav rootpage back to the login, the tabs are displayed at the bottom.
b. Create the login page as a modal which removes the problem of the tabs appearing at the bottom, but I'm not sure if I should be firing the modal from app.ts since I'm not sure if the application itself has a root view I should be referencing.
Also, should I set up the auth login and logout as a service and refactor it out rather than having it in the login page and the logout button in the profile controllers?
Here's my logic thus far using method A:
app.ts
export class MyApp {
rootPage: any;
local: Storage = new Storage(LocalStorage);
constructor(platform: Platform) {
this.local.get('user').then(user => {
if (user) {
this.rootPage = TabsPage;
} else {
this.rootPage = LoginPage;
}
});
platform.ready().then(() => {
StatusBar.styleDefault();
});
}
}
And in myProfile.ts
logout() {
this.local.remove('user');
this.user = null;
let modal = Modal.create(LoginPage);
this.nav.present(modal); //should I set the rootPage instead? if so how do I remove the tabBar or set the rootpage of the containing app root page
}
a. Check for session/localStorage on app.ts and set the rootPage to
login if unauthenticated? Using this method if I log the user out and
set the nav rootpage back to the login, the tabs are displayed at the
bottom.
You can use Angularfire2 Ionic Provider , Go to this link for more details Angularfire2 Auth with Ionic
import { Observable } from 'rxjs/Observable';
import { Injectable } from '#angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
// Do not import from 'firebase' as you'll lose the tree shaking benefits
import * as firebase from 'firebase/app';
#Injectable()
export class AuthService {
private currentUser: firebase.User;
constructor(public afAuth: AngularFireAuth) {
afAuth.authState.subscribe((user: firebase.User) => this.currentUser = user);
}
getauthenticated(): boolean {
return this.currentUser !== null;
}
signInWithFacebook(): firebase.Promise<any> {
return this.afAuth.auth.signInWithPopup(new firebase.auth.FacebookAuthProvider());
}
signOut(): void {
this.afAuth.auth.signOut();
}
displayName(): string {
if (this.currentUser !== null) {
return this.currentUser.facebook.displayName;
} else {
return '';
}
}
}
Then from App.ts Import the Provider you just created and then check for Auth status
constructor(public authService: AuthService) {
let authState = this.authservice.getauthenticated();
if (authState) {
this.rootPage = TabsPage;
} else {
this.rootPage = LoginPage;
}
}
And Finally for the Logout use Navigating from an Overlay Component
import { App } from 'ionic-angular';
constructor(
public appCtrl: App
) {}
setRoot(Page:any) {
this.appCtrl.getRootNav().setRoot(Page);
This will not display the Tabs in bottom.
Here's an example of an ionic login flow with a jwt stored in the local storage:
https://github.com/RedFroggy/ionic2-nfc-app/tree/master/app/pages/login