I am calling await FirebaseFirestore.instance.clearPersistence(); in-order to clear the cached data after a user signed out.
Per the documentation, you only call it after terminating the firestore session.
But after trying to retrieve the data again after login, I am getting an error:
"The client has already been terminated"
EDIT: THIS HAPPENS ONLY ON FLUTTER WEB. On flutter mobile (Tested on Android) it is working fine.
So how can I initialize the instance after terminating it?
await FirebaseFirestore.instance.terminate();
await FirebaseFirestore.instance.clearPersistence();
Related
I need a callback URL so that when a mobile money API completes a payment transaction, my app can receive a message about the transaction status. I'm building a flutter app. I have seen that cloud functions may be the answer. So, I need help on how to get started on creating this callback URL.
I'm yet to try anything because all the material I have seen talks about JavaScript and websites. I need material on doing this in the flutter mobile app.
look at this snippet I hope it helps
// await for your first function t
await moneyFuntion()
.whenComplete(() async => await anotherAPIFuntion())
.onError((error, stackTrace) {
log("$error");
I am using the getstream api and I would like to enable push notification services on both android and ios devices. The documentation just shows various excerpts on various parts of the process and I don't understand why. This is a nuanced topic and detailed step by step process should be the standard.
But essentially, I am not sure how to add a device to a client.
I have tried the below (which i'm not sure is the right way to go about it, but the documentation is not clear) but I get an unauthorized token error:
_invokeGetStreamApiFcmToken() async {
final client = StreamChatCore.of(context).client;
//listen for fcm token refresh
FirebaseMessaging.instance.onTokenRefresh.listen((token) {
client.addDevice(token, PushProvider.firebase);
print("get stream api token refreshed -- $token");
});
print(await FirebaseMessaging.instance.getToken());
print(await FirebaseMessaging.instance.getAPNSToken());
// register the device with APN (Apple only)
await client.addDevice(uid, PushProvider.apn);
// register the device with Firebase (Android only)
await client.addDevice(uid, PushProvider.firebase);
print(await client.getDevices());
}
In the client.addDevice() method, I am not sure at all what the first parameter, "device id" is meant to be. How do i get this device ID?
In my home page , i need to get current user data every time when user open app.
But i want to get this data from cache.
As per the documentation offline Persistence is by default in android and iOS.
UserRef.doc(FirebaseAuth.instance.currentUser.uid).get()
.then((DocumentSnapshot snapshot) {
if(snapshot.exists){
print('this is exists');
userExistence=true;
setState(() {
});
}
these code i run in initState but it is not getting from offline cache
When the app is not connected/cannot connect to the database server, the get() call will already return the results from the local cache. This may take some time if this is the first time you call Firestore, as the client in that case will try to reach the server first - and only returns results from the cache once that connection fails.
If you already know that the client doesn't have an internet connection, you can speed up the get call by specifying that it must return results from the cache:
get(GetOptions(source: Source.cache))
Also see the documentation for DocumentReference.get().
I'm new to firebase messaging and flutter. According to the flutter firebase_messaging package docs, onTokenRefresh is fired when a new FCM token is generated. And according to Google's firebase docs there are two scenarios that triggers token generation:
When a new token is generated on initial app startup
Whenever an existing token is changed
Here is a simplified version of the main function of my application. After each execution, I delete the app from the emulator and the displayed token does indeed change. Despite this, onTokenRefresh is never fired and it should if my understanding of the documentation is correct.
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.instance.onTokenRefresh.listen((String token) {
print("New token: $token");
});
String token = await FirebaseMessaging.instance.getToken();
print("Token: $token");
//runApp(MyApp());
}
As I said, I'm new to flutter, dart and firebase messaging, is there something I'm fundamentally misunderstanding? Thanks.
So I think I figured it out. I noticed that sometimes, the onTokenRefresh does indeed fire. And I was wondering if it had something to do with how the flutter application is launched onto the emulator, in the sense that there is a race condition between when the token is generated and the listener attached.
To get the app to appear to start for the first time, I wiped the app data. Unfortunately this causes the flutter to automatically disconnect from the app which means I won't see the output of the print statement. So instead of trying to print when the token generation occurs, I assigned a value from the onTokenRefresh listener to a variable. I then updated a text widget with the value of the variable. And onTokenRefresh does indeed fire each time at start up if the app data has previously been wiped.
I am using Flutter Drive for integration tests. The tests works well until app shows push notification consent. It seems Flutter Drive doesn't recognise the pop-up by iOS and crashes it there.
takeScreenshot(driver,"screenshots/01.login_screen_initial.png");
await driver.tap(tfUserId);
await driver.enterText('100111');
await driver.tap(tfPassword);
await driver.enterText('abc');
takeScreenshot(driver,"screenshots/02.login_screen_before_button_tap.png");
await driver.tap(loginButton);
After this button tap, the app asks for push notification consent. And the following code never gets executed.
takeScreenshot(driver,"screenshots/03.login_screen_just_after_button_tap.png");
await driver.waitForAbsent(btnHRDirectory,timeout: Duration(seconds: 360));
takeScreenshot(driver,"screenshots/04.dashboard_screen.png");
I get error as :
[VERBOSE-2:rasterizer.cc(307)] Last layer tree was null when screenshotting.
Detailed error is here.
The issue was somewhere in the script. driver.WaitFor along with timeout duration helps. No problem for the pop-up as Flutter Drive waits for the pop-up to vanish.