Comments (10)
Hey, ermagerd, so sorry I missed this notification! I'll take a look this evening and report back :)
Thanks for the kind words and submitting this issue!
from flutter_redux.
No problem at all, thanks for being available to answer these questions!
from flutter_redux.
Hey there! Reading through the code, I don't see anything obviously wrong... You mentioned an error: Could you describe what error you're running into? Are you getting an error from the Flutter framework itself or from Firebase / parsing?
Just to be sure: You're providing the navigatorKey
to your MaterialApp
as well, correct? Once that's in place, it should work without a context unless you're calling this action before the MaterialApp
is in place and has constructed the NavigatorState.
from flutter_redux.
Coded up a quick example showing navigation with a Middleware if this helps: https://github.com/brianegan/flutter_redux/blob/simple-navigation-example/example/lib/main.dart#L20
from flutter_redux.
Hi, thanks for the quick response!
The issue is that the google_sign_in
plugin is unable to run its signIn()
method found in my signIn()
method in the SignIn
class. The method simply returns null without prompting the user to sign in, which it was able to do before I switched to Redux. I don't know if this is a problem that is under the scope of your plugin or not, but I figured I might as well try and ask.
The prompt that google_sign_in
should provide is not something that I created myself, before it would just overlay over whatever I currently had on screen without the need for a Navigator
or BuildContext
. To be honest I don't really know how it worked.
Something that could possibly help: do you know of any examples where someone has successfully used the google_sign_in
plugin in conjunction with your flutter_redux
plugin?
Thanks again.
from flutter_redux.
No worries! I work on both redux and this plugin, so happy to cover both scopes :)
google_sign_in
shouldn't need context or anything like that. Generally, it will open a native view on Android or iOS rather than displaying flutter widgets.
I tried a simplified test case to see if google sign in works within Middleware. When you tap the Button, it should launch google sign in from within the middleware. This worked from my end, does it work for you?
Hrm, there are some projects I know of that use them in combination, but they're private repos or companies :(
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:redux/redux.dart';
void main() => runApp(new MyApp());
final _googleSignIn = new GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
);
void signInMiddleware(
Store<String> store,
dynamic action,
NextDispatcher next,
) {
next(action);
try {
_googleSignIn.signIn();
} catch (error) {
print(error);
}
}
final store = new Store<String>((state, action) => action.toString(),
middleware: [signInMiddleware]);
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'You have pushed the button this many times:',
),
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: () {
store.dispatch("Sign in");
},
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
from flutter_redux.
I was somehow able to fix the problem by making my GoogleSignIn
instance a non-static field within the SignIn
class rather than a static field in a different class (do you have any insight into why this worked?).
I have, however, run into another problem. It seems that calling the googleSignIn.signIn()
method works, but for some reason it does not return the signed in account. I must call googleSignIn.signInSilently()
afterwards in order to get a reference to the signed in account.
I found this out because I had to press my "sign in" button twice. The first time gave me the correct prompt, but set the account to null
which then threw an error (which I caught). The second time pressing the button worked with a silent sign in (no prompt).
Any idea why this might be happening? Attached is the updated relevant code:
SignIn
/// Performs sign in operations with real network data.
class SignIn extends ISignIn {
final IProfileStore store;
final GoogleSignIn googleSignIn = new GoogleSignIn(scopes: [
"email",
"https://www.googleapis.com/auth/contacts.readonly",
]);
SignIn() : store = new ProfileInjector().profileLoader;
Future<ProfilePackage> signIn() async {
// Check to see if there is currently a signed in user.
final GoogleSignInAccount account = googleSignIn.currentUser;
// Try to sign in without prompting the user.
if (account == null) {
account == await googleSignIn.signInSilently();
}
// If this doesn't work, prompt the user to sign in.
if (account == null) {
account == await googleSignIn.signIn();
}
// If this doesn't work, throw an error that should tell the user that
// they must sign in.
if (account == null) {
throw new StateError("The user must log in.");
}
final GoogleSignInAuthentication auth = await account.authentication;
// Authenticate the user with firebase.
final FirebaseUser user = await Networking.firebaseAuth
.signInWithGoogle(idToken: auth.idToken, accessToken: auth.accessToken);
if (user == null || user.isAnonymous) {
throw new StateError("Log in error.");
}
final ProfilePackage package = await store.loadProfile(user.uid);
// No user was found, so create a new one and save it to the database.
if (package == null) {
ProfilePackage newPackage =
new ProfilePackage.fromGoogleSignIn(account, user);
await store.saveProfile(newPackage);
return newPackage;
} else {
return package;
}
}
Future<Null> signOut() async {
await googleSignIn.signOut();
await Networking.firebaseAuth.signOut();
}
Future<Null> signOutAndDelete(String uid) async {
await store.deleteProfile(uid);
await signOut();
}
}
Middleware
for good measure
/// Creates the [Middleware] associated with a sign in attempt.
Middleware<AppState> _createSignIn(ISignIn signIn) {
return (Store<AppState> store, action, NextDispatcher next) {
signIn.signIn().then(
(user) {
store.dispatch(
new SignedInAction(
new Profile.fromPackage(user),
),
);
Keys.navigatorKey.currentState
.pushReplacementNamed(InternalStrings.mainScreenRoute);
},
).catchError(
(_) {
store.dispatch(new FailedSignInAction());
},
);
next(action);
};
}
from flutter_redux.
"I was somehow able to fix the problem by making my GoogleSignIn instance a non-static field within the SignIn class rather than a static field in a different class (do you have any insight into why this worked?)."
Dart is a bit weird about statics... if you use them in one file it will create the object, then if you use them in another file after importing it will recreate the object :( Don't ask me why :(
Because of that, I generally avoid statics unless I'm hacking something together quickly for an idea.
"I have, however, run into another problem. It seems that calling the googleSignIn.signIn() method works, but for some reason it does not return the signed in account"
Unfortunately, I'm not sure why that would be the case. Did it work before you introduced Redux? If not, you'd probably have to file a bug against the Flutter repo.
from flutter_redux.
Dart is a bit weird about statics... if you use them in one file it will create the object, then if you use them in another file after importing it will recreate the object :( Don't ask me why :(
Wow, that's good to know, thank you for that insight. I'll be sure to rearrange the rest of my code to avoid them as much as possible.
Unfortunately, I'm not sure why that would be the case. Did it work before you introduced Redux? If not, you'd probably have to file a bug against the Flutter repo.
It did work before, I'll go ahead and mess around with it to see if I can't figure out why it's broken.
Thank you again for your help, you're a lifesaver.
I will go ahead and mark this as closed.
from flutter_redux.
Sure thing, thanks for the Qs! Best of luck with the app :)
from flutter_redux.
Related Issues (20)
- How to not accept change notifications when the Router is not at the top level, and then take the initiative to obtain the changes when the Router returns to the top level HOT 1
- onDidChange called twice HOT 8
- Is this package still actively maintained?
- `onWillChange` and `onDidChange` errors are swallowed HOT 4
- Warning related to `?` operator on Linux/Dev channel. HOT 2
- Import Store data type
- Widgets binding error after upgrading flutter version to 2.13.0-0.1.pre HOT 1
- onDidChange not working as expected HOT 3
- Build warning with Flutter 3.0 HOT 5
- flutter_redux depends on flutter_redux, version solving failed HOT 3
- onWillChange and onDidChange called twice after state update HOT 2
- Passing Store as an argument to MethodChannel and Background Isolate
- Question on how to use the reducer right way HOT 2
- [Question]: Any thoughts on difference between ignoreChange and distinct?
- Socket and Flutter_redux HOT 18
- Dispatching an action that does not alter state rerenders the widget, causing an infinite loop HOT 5
- How to watch redux store change inside useEffect? HOT 5
- [Question] is it expected that the store doesn't run until frames render? HOT 1
- After push a new page, and Dispatching an action, there is an infinite loop
- Is flutter redux actively maintained HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flutter_redux.