Subscription Data Arrives Very Late Meteor - React Native Meteor - meteor

After publishing data and subscribing from react native client,it takes about a minute to make subscribtion ready.If i update collection it takes again about a minute to get data and fire componentWillReceiveProps(newProps) method.Collection has only few documents.
Meteor Server Code:
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { ArtWorks } from './database/artworks';
import { Gallerys } from './database/gallerys';
import { PlayerData } from './database/playerdata';
import { Questions } from './database/questions';
import { Relics } from './database/relics';
import { RelicsOnMap } from './database/relicsonmap';
Meteor.startup(() => {
});
Meteor.publish('getRelicsOnMap', function getRelicsOnMap (){
console.log("publishing...")
return RelicsOnMap.find({});
});
RelicsOnMap collection:
import { Mongo } from 'meteor/mongo';
export const RelicsOnMap = new Mongo.Collection('relicsonmap');
Client:
import React, { Component } from 'react';
import { View } from 'react-native';
import {
Container,
Header,
Title,
Content,
Button,
Item,
Input,
Body,
Left,
Right,
Icon,
Form,
Text,
Spinner,
Toast
} from "native-base";
import Meteor,{withTracker} from 'react-native-meteor';
class ProfileScreen extends Component {
constructor(props) {
super(props);
this.userData;
this.state = {
};
}
componentDidMount(){
console.log(this.props)
}
componentWillReceiveProps(newProps){
console.log(newProps)
}
render() {
return (
<Container>
<Text>This is Profile screen</Text>
<Text>This is Profile screen</Text>
</Container>
);
}
}
export default withTracker(params => {
Meteor.subscribe('getRelicsOnMap');
return {
relicsOnMap: Meteor.collection('relicsonmap').find({})
};
})(ProfileScreen);
I do Meteor.connect in another component and its succesfull.
Here there is a small video me demonstrating the problem:
http://sendvid.com/v5fqlurh

I found out that react natives remote debugger causes this problem.When im not connected to my local network for debugging through google chrome,everything is fine.I guess this is a bug.

Related

Ionic "await signInWithEmailAndPassword()" not working on iOS simulator/device without livereload

In my Ionic 5 capacitor app, I have a button that calls this function
import {
signInWithEmailAndPassword, signOut,
User, UserCredential,
} from '#angular/fire/auth';
//...blah blah blah
async signIn(value)
{
try {alert('signing in')
return (await signInWithEmailAndPassword(this.auth, value.email, value.password)).user
} catch (error) {
alert('what the heck?' + error)
}
}
This works fine on the web and on Android (it returns the object and proceeds). On iOS simulator & the device, it works with livereload, but without livereload, it does nothing, not even return anything. The 'signing in' pops up, but doesn't proceed from there.
Any idea why this is the case?
In your app.module.ts file, add the following to your imports array.
provideAuth(() => {
if (Capacitor.isNativePlatform()) {
return initializeAuth(getApp(), {
persistence: indexedDBLocalPersistence,
});
} else {
return getAuth();
}
}),
and import the necessary functions & values from #angular/fire/auth.
This is a similar solution to Puneet Kushway. I find this solution better, as it keeps your app.component.ts file uncluttered.
After struggling, luckily I found what needs to be done.
In your app.component.ts add below code :
import { Component } from '#angular/core';
import { Capacitor } from '#capacitor/core';
import { initializeApp } from 'firebase/app';
import { indexedDBLocalPersistence, initializeAuth } from 'firebase/auth';
import { environment } from 'src/environments/environment';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
})
export class AppComponent {
constructor() {
const app = initializeApp(environment.firebase);
if (Capacitor.isNativePlatform()) {
initializeAuth(app, {
persistence: indexedDBLocalPersistence
});
}
}
}

How to Debug White Screen Page (No Content Showing) in RN Expo App with No Error Prompts

I've been building an app in React Native Expo. First, I incorporated Facebook Login simply by copying and pasting the login async code into Login.js and added this.login() to componentWillMount. This worked - With the Facebook login popup showing up as app loads. I was able to log into my FB account with a success message.
However, as soon as I tried to incorporate Firebase, particularly somewhere between transferring code between my Home.js page and the Login.js page, I started getting this white screen to appear on page load.
There are no errors in a terminal; except a message that FacebookAppID and facebookDisplayName do not belong in app.json.
I tried adding a different background color (black) in CSS, which works, but still, there is no content.
Removing FacebookAppID and facebookDisplayName from app.json, which did nothing.
Updating my App Key to the correct one (I was missing the last number).
Restarted the terminal, expo web terminal x code and metro builder several times.
Updated my code so that every file in my Screens directory has { connect } & { login } imports as well as functionMapStateToProps and export default connect statements at bottom.
I tried changing a tab in TabNavigator.js to Login page, and using "Login" as the initialRouteName, but got an error that Login.js isn't a React component.
The first page that should show up before any other is the Facebook login...So it would seem the issue is there.
App.js
import React from 'react';
import Login from './screens/Login';
import reducers from './redux/reducers';
import thunkMiddleware from 'redux-thunk';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
const middleware = applyMiddleware(thunkMiddleware);
const store = createStore(reducers, middleware);
export default class App extends React.Component {
render() {
return (
<Provider store={store}>
<Login/>
</Provider>
);
}
}
------ end of App.js ------------
Login.js
import React from 'react';
import styles from '../styles'
import RootNavigator from '../navigation/RootNavigator';
import { connect } from 'react-redux';
import { login } from '../redux/actions';
import * as firebase from 'firebase';
import firebaseConfig from '../config/firebase.js';
firebase.initializeApp(firebaseConfig)
import {
Text,
View,
TouchableOpacity
} from 'react-native';
class Login extends React.Component
state = {}
componentWillMount() {
firebase.auth().onAuthStateChanged((user) => {
if (user != null) {
this.props.dispatch(login(true))
console.log("We are authenticated now!" + JSON.stringify(user));
}
});
}
login = async () => {
const { type, token } = await Expo.Facebook.logInWithReadPermissionsAsync('YourAppKeyGoesHere', {
permissions: ['public_profile'],
});
if (type === 'success') {
// Build Firebase credential with the Facebook access token.
const credential = await firebase.auth.FacebookAuthProvider.credential(token);
// Sign in with credential from the Facebook user.
firebase.auth().signInWithCredential(credential).catch((error) => {
// Handle Errors here.
Alert.alert("Try Again")
});
}
}
render() {
if(this.props.loggedIn){
return (
<RootNavigator/>
)
} else {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.login.bind(this)}>
<Text>{this.props.loggedIn}</Text>
</TouchableOpacity>
</View>
)
}
}
}
function mapStateToProps(state) {
return {
loggedIn: state.loggedIn
};
}
export default connect(mapStateToProps)(Login);
---------end of Login.js ----------
Home.js
import React from 'react';
import styles from '../styles';
import { connect } from 'react-redux';
import { login } from '../redux/actions';
import {
Text,
View,
Alert
} from 'react-native';
class Home extends React.Component {
state = {}
componentWillMount() {
}
render() {
return (
<View>
<Text>Home</Text>
</View>
)
}
}
function mapStateToProps(state) {
return {
loggedIn: state.loggedIn
};
}
export default connect(mapStateToProps)(Home);
-----end of Home.js ------
redux folder
actions.js
export function login(){
return function(dispatch){
dispatch({ type: 'LOGIN', payload: input });
}
}
----end of actions.js ----
reducers.js
export default reducers = (state = {
loggedIn: false,
}, action) => {
switch (action.type) {
case 'LOGIN': {
return { ...state, loggedIn: action.payload }
}
}
return state;
}
------end of reducers.js ------
-----end of redux folder ------
-----navigation folder (react navigation) -------
---RootNavigator.js---
import React from 'react';
import TabNavigator from './TabNavigator';
import {
createDrawerNavigator,
createStackNavigator,
createBottomTabNavigator,
createAppContainer,
} from 'react-navigation';
const AppNavigator = createStackNavigator(
{
Main: {
screen: TabNavigator,
},
}
);
const AppContainer = createAppContainer(AppNavigator);
export default class RootNavigator extends React.Component {
render() {
return <AppContainer/>;
}
}
----end of RootNavigator.js-----
----TabNavigator.js----
import React from 'react';
import Home from '../screens/Home';
import Profile from '../screens/Profile';
import Matches from '../screens/Matches';
import {
createDrawerNavigator,
createStackNavigator,
createBottomTabNavigator,
createAppContainer,
createMaterialTopTabNavigator,
} from 'react-navigation';
export default createBottomTabNavigator(
{
Profile: {
screen: Profile,
navigationOptions: {
tabBarLabel: 'Profile',
},
},
Home: {
screen: Home,
navigationOptions: {
tabBarLabel: 'Home',
}
},
Matches: {
screen: Matches,
navigationOptions: {
tabBarLabel: 'Matches',
},
},
},
{
navigationOptions: {
header: null
},
tabBarPosition: 'top',
initialRouteName: 'Home',
animationEnabled: true,
swipeEnabled: true,
tabBarOptions: {
style: {
height: 75,
backgroundColor: 'blue'
},
}
}
);
-----end of TabNavigator----
Have you tried remote js Debugging?
What you can do is, Debugg JS remotely.
https://developers.google.com/web/tools/chrome-devtools/remote-debugging/
try to console.log("hi"); when your first component of your app mounts.
Try to add it in login page when the login component mounts.
That will help you debug unseen error which gets listed in the js debugger.
Just check those errors and follow up!
You're good to go!
I was also getting splash logo white screen, tired possible solution nothing works out, at last I have remove node_module and yarn.lock. then reinstall and update expo
follows cmd:-
$ npm install
$ yarn add expo
$ expo update
try this , works for me.
!!enjoy!!
As the other answer suggests, once you've done console.log to see the component is actually loading, then for me the issue was I couldn't actually see the content.
My solution was to wrap my content with a <View> to align the content in the middle of the page.
I understand your question is more complex than that, but hopefully, my answer might be able to help other people.
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'space-around',
}}>
<Text>Can you see this?</Text>
</View>
in my case,
style = {{ borderColor : #fff }}
my mistake is exceptin ' at borderColor value...
fix change to
style = {{ borderColor : '#fff' }}
Some components such as useState was imported from wrong url, I changed it and imported it from react and fixed it

React Native Firebase Change initialRoute if logged in

I'm using React Native 0.36 and Firebase. How do I make the homepage of the app change if a user is logged in. I tried an if statement in renderScene but it gives this error:
index.ios.js
import React, { Component } from 'react';
import {
AppRegistry,
Navigator,
} from 'react-native';
import firebase from 'firebase';
import Login from './Login';
import Home from './Home';
function renderScene(route, navigator) {
return <route.component route={route} navigator={navigator} />;
}
export default class Snip extends Component {
renderScene(route, navigator){
return <route.component navigator={navigator} />
}
render() {
var that = this;
firebase.auth().onAuthStateChanged(function(user) {
if(user) {
return (
<Navigator
initialRoute={{component: Home}}
renderScene={that.renderScene}/>
)
} else{
return (
<Navigator
initialRoute={{component: Login}}
renderScene={that.renderScene}/>
)
}
});
}
}
There are two things that are wrong with the code from the question.
You cannot return a react element inside of a firebase callback
Firebase takes a moment to return if the user exists. So I have to create a loading state that get updated. When firebase is done.
index.ios.js
import React, { Component } from 'react';
import {
AppRegistry,
Navigator,
View,
Text,
} from 'react-native';
import firebase from 'firebase';
import Login from './Login';
import Home from './Home';
function renderScene(route, navigator) {
return <route.component route={route} navigator={navigator} />;
}
export default class Snip extends Component {
constructor(props) {
super(props);
this.state = {
user: null,
loading: false
};
}
componentWillMount() {
var that = this;
firebase.auth().onAuthStateChanged(function(user) {
if(user) {
that.setState({
user: user,
loading: false
})
}else{
that.setState({
loading: false
})
}
});
}
renderScene(route, navigator){
return <route.component navigator={navigator} />
}
render() {
if(this.state.loading){
return <View><Text>loading</Text></View>;
}else if(this.state.user){
return(
<Navigator
initialRoute={{component: Home}}
renderScene={this.renderScene}/>
)
}else{
return (
<Navigator
initialRoute={{component: Login}}
renderScene={this.renderScene}/>
)
}
}
}

Displaying Meteor.user().username using Tracker React

I have been trying to display the Username of a Logged in user using Tracker React.
I have removed the auto-publish package.
/Client/components/dashboard/sidebar.jsx
import React, {Component} from 'react'
import TrackerReact from 'meteor/ultimatejs:tracker-react';
export default class Sidebar extends TrackerReact(Component) {
constructor() {
super();
this.state = {
subscription: {
users: Meteor.subscribe('users')
}
};
}
render() {
return(
<div>
<h1>{Meteor.user().username}</h1>
</div>
);
}
/Server/publications/userPublications
Meteor.publish("users", function () {
return Meteor.users.find();
});
I am getting a null object while console.log(Meteor.user()). However, I can see the current username using the Meteor DevTools for chrome.
What block of puzzle am I missing?
I doubt you can use Meteor.user(). username
Try this instead
<h1>{{currentUser}}</h1>
You can use createContainer in order to manage it.
import { Meteor } from 'meteor/meteor';
import React, { Component, PropTypes } from 'react';
import { createContainer } from 'meteor/react-meteor-data';
export class Sidebar extends Component {
static propTypes = {
loggedIn: PropTypes.bool.isRequired,
loggingIn: PropTypes.bool.isRequired,
currentUser: PropTypes.shape({
username: PropTypes.string
})
}
render() {
const { loggingIn, loggedIn } = this.props;
return (
<div>
{(() => {
if (loggingIn) {
return <Loading />
} else if (loggedIn) {
// whatever you want here.
} else {
<h1>Please Log In</h1>
}
})()}
</div>
)
}
}
export default createContainer(() => ({
user: Meteor.user(),
loggedIn: !Meteor.userId(),
loggingIn: Meteor.loggingIn()
}), Sidebar);
A few details here:
Meteor.loggingIn() is a reactive variable that is run while the user is logging in. When this is happening, there will not be a user object.
You should create a reactive container

Meteor/React - display all users (publish all users to the client )

I'm using Meteor/React and I'm trying to display all the users in the system:
I have: /imports/api/users.js
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
if (Meteor.isServer) {
// This code only runs on the server
// Only publish tasks that are public or belong to the current user
Meteor.publish('allUsers', function () {
return Meteor.users.find({}, {fields: {"emails.address": 1}});
});
}
and /imports/ui/App.jsx
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
class App extends Component {
constructor() {
super();
this.state = {
subscription: {
users: Meteor.subscribe('allUsers')
}
}
}
componentWillUnmount() {
this.state.subscription.users.stop();
}
render() {
let users = this.props.users;
console.log(users);
return (<div>
<h1>GoArc User Manager</h1>
<div>
{users.map((user)=>{
if ('emails' in user ) {
email = user.emails[0].address;
} else {
email = '?'
}
return <div key={user._id}>{user._id} - {email}</div>
})
}
</div>
</div>)
}
}
export default createContainer(() => {
return {
users: Meteor.users.find({ }).fetch(),
};
}, App);
But it still show only the current login user.
If I set autopublish/insecure on then the code is working correct.
What is the correct way to publish all users to the client with Meteor/React?
Another related issue is that even when I set autopublish/insecure on still the email.address field appear only for the current user - even though I published this field:
return Meteor.users.find({}, {fields: {"emails.address": 1}});
The code is correct but I forgot to add import '../imports/api/users.js';
in /server/main.js

Resources