Flutter reset all provider states after sign out - flutter

Whenever I sign out of my app, it seems to not clear all provider states and when I log in to another user my app crashes. Is there way to reset everything to default when performing logout action?

It depends on the scope of your provided objects. If you provide them at top level, the instances will not be disposed and live on.
Possible solutions could be:
Provide your state further down in the widget tree.
Observe a logout event in your state and perform reset of state automatically. There are multiple ways to do this, e.g. use a ProxyProvider.
ProxyProvider<Session, SomeStateClass>(
create: (_) => SomeStateClass(),
update: (_, session, instanceOfStateClass) {
return instanceOfStateClass..reinitialize(session);
}),
In the example above, the update method gets called, when Session notifies about changes.

Related

Flutter GetX Auth ever function

I am completely new to GetX and want to learn an easier state management system than bloc ( I started with BLoC). So the first thing I wanted to learn is how authentication works. I found this tutorial online: https://dev.to/imransefat/firebase-authentication-with-getx-in-flutter-4ik8 and asked me a question.
Inside the controller, the author bound two streams. One for the user and one for the googleSignInUser and he also added an ever function for googleSignIn:
googleSignInAccount.bindStream(googleSign.onCurrentUserChanged);
ever(googleSignInAccount, _setInitialScreenGoogle);
. When I user exactly this source-code and add a Firestore crud controller with a Todo-list, I get a null value on the variable auth.currentUser! on the Stream for the Todo list ( firebaseFirestore.collection('/users/${**auth.currentUser!**.uid}/FoodList').snapshots().map((QuerySnapshot query) {... )
When I remove this function inside the onReady method, everything works fine. If I understand this correctly, I don't have to listen to the googleSignIn stream specifically, it should be enough to listen to the user stream. Is this a mistake from him, or do I misunderstand here something? You can find the complete source code on the website.
Second question is: Before GetX I always check if a user is authenticated or not with a StreamBuilder inside the Material app:
StreamBuilder<User?>(
stream: auth.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return const RootPage();
} else {
return TutorialRoot();
}
With GetX I saw this appoach with the _setInitialScreen(User? user) method and the
ever(firebaseUser, _setInitialScreen);
call inside the onReady(); - Is the StreamBuilder a bad practice when using GetX, or still a legit way of checking the current auth status? In my opinion the user expirince is a little bit faster with the StreamBuilder that why I ask for this.

How to prevent other widgets from staying active when leaving them in flutter

I have an app with many pages/interfaces and most of them are getting the data from an api, when i leave a page and go to another, the previous one stays active forever.
I noticed that when prenting the data result on every page and i noticed even when i leave the page before finishing it job, it keep fetching the data at the same time with the next page that i opened.
This caused me many problems when checking many pages one after another and made the app lag or close connection with the api.
I want to know how to prevent this from happenening
This is how i go from one page to another
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context)=>Dashboard()
));
You need to dispose the previous page. You can do it by pushReplacement route state. It will dispose all your previous page's methods which are currently running.
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (BuildContext context)=>Dashboard()
));

Fiori launchpad: handle logout event with custom backend call without `attachLogoutEvent` (UI5 < 1.81)

So, I found that the launchpad Container API provides an option to register a logout event with returning a promise (https://ui5.sap.com/#/api/sap.ushell.services.Container%23methods/attachLogoutEvent).
Unfortunately, after the implementation I found out that the UI5 version must be 1.81 or higher for parameter bAsync to work. In my project, we're at 1.78, so no promises for me.
What's the problem?
I want to make a backend call in the said logout event. This doesn't work, since, as far as I understood my debugging, the launchpad destroys everything just after my logout event has "finished" (= every line of code in the event has been gone through, ignoring sub-functions). Timeouts etc. don't work, because their calls would also be after code progressing has already finished, meaning the calls are deleted.
What have I tried?
Instant backend call without sub-functions → didn't work for the same reason as above.
Infinite while-looping until the backend call is processed → stack overflow.
While-looping with timeout/await → await not allowed in strict mode, timeout didn't work because of the above issue.
What do I think might work?
Stall code progression until the backend call has been finished.
Using a completely different method to get my logic into handling the logout (e.g. full custom logout).
Ask here for further ideas.
Does anyone have an idea on how to solve the issue with UI5 1.78?
Alright, I have found a solution to this. It's probably not the technically nicest, but it works and the result looks clean enough. This is from a S4/HANA system, so it might not be a universal solution (e.g. it doesn't consider logging off within the left-side pane which doesn't exist in my launchpad).
What did I do?
Instead of attaching my individual logic to the Fiori logout-event, I created a custom logout button with my individual logic, followed by calling the SICF logout node.
How did I do it?
Create a Launchpad plugin
In Component.js, add a new header item with custom logout function
// ushellLib required from "sap/ushell/library"
var oRenderer = ushellLib.Container.getRenderer("fiori2");
oRenderer.addHeaderEndItem("sap.ushell.ui.shell.ShellHeadItem", {
id: "logoutButton",
icon: "sap-icon://log",
// ...
press: [this._logout, this],
}, true, false);
_logout: function() {
this._callMyStuff();
window.location.href = "/sap/public/bc/icf/logoff";
},
In style.css, hide the original logout button (logoutBtn) in desktop (__list0...) and mobile (__list1...) to prevent skipping my logic by logging off via default logout.
#__list0-7-logoutBtn {
display: none;
}
#__list1-7-logoutBtn {
display: none;
}

Recognize removal of Widget in Cockpit Dashboard on Cumulocity

Is there a way (maybe an event or something we can subscribe to) to acknowledge inside a self implemented widget, whenever this or another widget is removed from the dashboard?
There is nothing like an event you can subscribe to.
In the end there will always be a PUT request to update the dashboard object whenever it changes. Maybe you can utilize that.

How to prevent code to execute after firing of history token in gwt?

I am working on gwt2.3 application with gwtp framework.In this application I am have one login (index) page which is bind by the client module.
bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.login);
Now after successfull login a new name token name user page is fired.
History.newItem(NameTokens.userconsole,true);
Now I have my history handler like below:
public class NameTokenHandler implements ValueChangeHandler {
#Override
public void onValueChange(final ValueChangeEvent<String> event) {
System.out.println("Nothing to do");
}
}
And I added to History like below in entry point class:
History.addValueChangeHandler(new NameTokenHandler());
Now as I have overridden the onValueChange method & I have left it blank.
So when application loads first or any other name token fires it should invoke onValueChange first
and as there no code in this method nothing should be load.
But in application it is working fine. All the name tokens are firing successfully even after there is no code in onValueChange. I am not getting how to prevent the firing of history token?
Please help me out.
Thanks in advance.
So when application loads first or any other name token fires it should invoke onValueChange first and as there no code in this method nothing should be load.
If you are using gwtp History ValueChangeHandler will not prevent or enable navigation to a particualr part of your application. That is all handled with PlaceManager.
After some googling I came to know about place manager.
I am adding_ a change handler to History. All the change handlers that
have been added already are still there. In particular, the one in GWTP's
PlaceManagerImpl constructor.
If you really want to prevent some history events from being handled by
GWTP, I would suggest that, in your custom PlaceManager, you
override onValueChange(...), intercept the tokens you want to block, and
call the parent's onValueChange for the tokens you want GWTP to handle
normally.