Flutter android_alarm_manager without firebase auth - firebase

I'm trying to use the Flutter android_alarm_manager to create some background tasks but can't seem to get it working without the firebase auth. I followed the readme on the plugin, but just adding the android_alarm_manager plugin in the pubspec.yaml causes the app to crash immediately (emulator and real device) on startup. How can I avoid the Firebase integration and still use the alarm manager plugin?

Re: but can't seem to get it working without the firebase auth
Maybe at the time of your attempt back in 2018, there was some unintended entangling or some other issue in your app, but as of now, https://pub.dev/packages/android_alarm_manager does not require any Firebase.
Just need to set up some permissions, a service, and receivers in the manifest, then this sample is runnable:
import 'package:android_alarm_manager/android_alarm_manager.dart';
void printHello() {
final DateTime now = DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");
}
main() async {
final int helloAlarmID = 0;
await AndroidAlarmManager.initialize();
runApp(...);
await AndroidAlarmManager.periodic(const Duration(minutes: 1), helloAlarmID, printHello);
}
Also see /flutter/android_alarm_manager/example/

Related

Inconsistency with Authenitcaiton User-Creation in Firebase React Native

I am trying to incorporate the Firebase JS SDK into a managed Expo React Native project. I installed Firebase through npm i firebase and I am using the latest version.
The problem is that whenever I start the expo app, through an Android emulator, I, when passing the input from formik into createUserWithEmailAndPassword first get the auth/network-request-failed error message, but after clicking the signup button several times, more than 10, it somehow works. The user is then added to the Firebase console. After this it works flawlessly, and I can create multiple accounts without fail. However, should I restart the app, then I would have to repeat the steps above.
I have divided the main firebase function to a separate file, and imported it.
The exported file:
import { initializeApp } from 'firebase/app';
import { getAuth, createUserWithEmailAndPassword } from 'firebase/auth';
import firebaseConfig from './app/config/Firebase/firebaseConfig';
let myApp = initializeApp(firebaseConfig);
const auth = getAuth(myApp);
export function signupEmail(email, password) {
console.log(email, password);
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
const user = userCredential.user;
console.log('Signed in');
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
});
}
The main parts of the sign-up file:
function handleSignup(values) {
signupEmail(values.email, values.password);
}
<SubmitButton
style={styles.signupButton}
title='SignUp'
onPress={handleSubmit}
/>
onSubmit={(values) => [handleSignup(values)]}
After pressing Signup I get the email and password printed out, as in the signupEmail function. I get the email and password message whether or not it is successful in the end, which I assume implies the problem doesn't lie with formik, since the data is correctly passed to the signupEmail function. Though, from here it often stands idle, sometimes for more than 10s before the network error message comes up. When it is successful, I think, is always instant.
I also have a print-out auth.currentUser button, which returns null whilst the process is loading, and if successful logs out the expected object. Though, sometimes it logs out the object to an account whose email that I didn't add during the current session. I did also add a Sign Out function which turns the auth.currentUser object into null.
I don't know where to go from here, and would appreciate any help!
This issue seems to be related to the Android emulator, Expo Go on my phone worked without issue.

How to send user location to Firestore even when app is killed in flutter?

I am trying to send user's location to Firestore even when the app is killed. I'm successfully able to send data to Firestore when the app is in the foreground or background but unable to send data when the app is killed. Can anyone explain what could be the problem?
I'm using
background_locator: ^1.6.4
Flutter
Flutter 2.2.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision f4abaa0735 (2 weeks ago) • 2021-07-01 12:46:11 -0700
Engine • revision 241c87ad80
Tools • Dart 2.13.4
Dart
Dart SDK version: 2.13.4 (stable) (Wed Jun 23 13:08:41 2021 +0200) on "linux_x64"
This code that I'm trying to execute once data is received
receiverPort.listen(
(dynamic data) async {
if (data != null) {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
final LocationDto position = data as LocationDto;
print('data: $position');
final Member member = await FirebaseService().getCurrentUserProfile();
member.currentPosition = '${position.latitude},${position.longitude}';
await FirebaseService()
.updateData(
FirebaseService.memberRef,
FirebaseService.memberChildId,
FirebaseService.getCurrentUserId(),
member.toJson())
.then((value) {});
} else {
print('data is null');
}
},
);
Please let me know if I need to share anything else. Thanks
I found the problem. I need to add Firestore code in the callback instead of in the ReceivePort.
Here is the working code:
Future<void> _startLocator() async {
final Map<String, dynamic> data = {'countInit': 1};
return BackgroundLocator.registerLocationUpdate(
LocationCallbackHandler.callback, // <-- You need to add your callback code here
initCallback: LocationCallbackHandler.initCallback,
initDataCallback: data,
disposeCallback: LocationCallbackHandler.disposeCallback,
iosSettings: const IOSSettings(
accuracy: location_settings.LocationAccuracy.BALANCED,),
androidSettings: AndroidSettings(
accuracy: location_settings.LocationAccuracy.BALANCED,
interval: 5,
androidNotificationSettings: AndroidNotificationSettings(
notificationChannelName: 'Location tracking',
notificationTitle:
location.isNotEmpty ? location : 'Start Location Tracking',
notificationMsg: 'Track location in background',
notificationBigMsg:
'Background location is on to keep the app up-to-date with your location. This is required for main features to work properly when the app is not running.',
notificationIconColor: Colors.grey,
notificationTapCallback:
LocationCallbackHandler.notificationCallback)));
}
Future<void> callback(LocationDto locationDto) async {
// Your call back code goes here
}
When the app's process is killed, all of its code stops executing. This includes any Firestore listeners. The OS does this in order to prevent an app from unexpectedly burning battery and data when the user isn't using it. This is a feature intended for the benefit of the end user, and your app should respect that.
See also:
Flutter: cross-platform way to keep application running in the background
How to keep my flutter app running in the background when close?
How do I run code in the background, even with the screen off?

Firebase Messaging 7.0.0 to 9.0.1 conversion

I'm trying to set up FCM for my iOS flutter app and followed the guide by flutter and even the guide from Fireship.io
I was working with an older version of FCM before I updated the dependencies and now there are methods that are deprecated or just plainly left out. I am unsure of which methods to replace these and I was unable to find resources on what exactly changed in between versions.
Below is my code from FCM 7.0.0
Code:
final FirebaseMessaging _fcm = FirebaseMessaging.instance;
StreamSubscription iosSubscription;
#override
void initState() {
super.initState();
if (Platform.isIOS) {
iosSubscription = _fcm.onIosSettingsRegistered.listen((data) {
// save the token OR subscribe to a topic here
});
_fcm.requestNotificationPermissions(IosNotificationSettings);
}
}
_saveDeviceToken() async {
// Get the current user
String uid = FirebaseAuth.instance.currentUser.uid;
// FirebaseUser user = await _auth.currentUser();
// Get the token for this device
String fcmToken = await _fcm.getToken();
// Save it to Firestore
if (fcmToken != null) {
FirebaseFirestore.instance
.collection('users')
.doc(uid)
.collection('tokens')
.add({
'token': fcmToken,
'createdAt': FieldValue.serverTimestamp(), // optional
'platform': Platform.operatingSystem
});
}
}
So my problems lie with the onIosSettingsRegistered line and the requestNotificationPermissions.
For both it says that method is not defined, because it has been deprecated or is no longer a valid method. Obviously, before updating my dependencies it worked fine no errors. I'm looking for resources revolving around Firebase cloud Messaging 9.0.1 that might show what was updated and what are the current methods to use.
The above answer is what lead me to fixing my issues. I'm just outlining below what I pulled from the guide the other user posted
FirebaseMessaging() no longer works and instead use
FirebaseMessaging.instance
IosNotificationSettings which was used with requestNotificationPermissions() can now be done with just RequestPermission()
Setting up a FCM.configure no longer works and you should just use FirebaseMessaging.onMessage(), FirebaseMessaging.onMessageOpenedApp, and FirebaseMessaging.onBackGroundMessage(). The last one can be paired with BkacgroundMessageHandeler in order to set up notifications when the app is closed or suspended.
And lastly, saving tokens still works the same as 7.0.0 as it does in 9.1.0 so no changes there.
9.1.0 brings null safety to the table so (depending on the rest of your dependencies) you can run the newest version of flutter with null safety with no issues.
Simple Google searches yielded the following results, perhaps you can try a bit harder before posting a question next time:
onIosSettingsRegistered is deprecated
Usage of the IosNotificationSettings class is now deprecated (currently used with the now deprecated requestNotificationPermissions() method).
Instead of this class, use named arguments when calling requestPermission() and read the permissions back via NotificationSettings.
requestNotificationPermissions deprecated too
DEPRECATED: requestNotificationPermissions() has been deprecated in favor of requestPermission().

AppleSignIn (with Firebase & Expo) working locally but not on standalone

I implemented the signinWithApple button on my Expo app, and it's working perfectly locally when i use the host.exp.Exponent on Services ID in Firebase authentification tab for Apple Sign in.
But when I create a standalone app, and I test it with TestFlight, it doesn't work anymore whether I use host.exp.Exponent, nothing, or my specific app service ID on Services ID.
What am I missing here?
MY CODE :
handleApple = async () => {
const csrf = Math.random().toString(36).substring(2, 15);
const nonce = Math.random().toString(36).substring(2, 10);
try {
const appleCredential = await AppleAuthentication.signInAsync({
requestedScopes: [
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
AppleAuthentication.AppleAuthenticationScope.EMAIL
],
state: csrf,
nonce: nonce
});
const {
identityToken,
fullName,
email
} = appleCredential;
if (identityToken) {
// login with credential
const provider = new firebase.auth.OAuthProvider("apple.com");
const credential = provider.credential({
idToken: identityToken,
rawNonce: nonce,
});
await firebase.auth().signInWithCredential(credential).then(user => {
...
EDIT :
I managed to make it work by using my bundle identifier (which is also my app id) on the Service ID field in firebase.
Error code :
Error: The audience in ID Token [##.app-videos] does not match the expected audience ##.signin.
But now the sign in with Apple on my website breaks.
I manage to make it work when I change the Service Id field to my specific app service ID (found in Identifiers > Services IDs).
So i'm stuck with an app that requires something and a website that requires an other. Why is that?
Should I do something specific when I rebuild my app so that the changes that I made to mu identifiers are taken into account?
I'm using this, is it not enough?
expo build:ios --clear-provisioning-profile
I had the same problem and should solve it in the following way.
You must re-create GoogleService-info.plist in the Firebase console with the same bundleId as in the project in Xcode.

Can't disable Crashlytics in a Firebase app (anymore)

After upgrading to com.crashlytics.sdk.android:crashlytics:2.7.1#aar (from 2.6.8), I can't disable Crashlytics anymore in my Firebase app.
Looks like there's some code in Crashlytics library itself that initializes Fabric with Crashlytics kit enabled whenever it detects that it's running inside a Firebase application. Indeed initializing with Crashlytics enabled and with ext.enableCrashlytics = false throws an UnmetDependencyException and crashes the app at startup (in fact, before my code in Application.onCreate runs).
Does anyone know a workaround for that? Sticking with 2.6.8 works for now.
This is what I have in my code that used to work until an upgrade:
app/build.gradle:
ext.enableCrashlytics = false
Application.java (onCreate, full method body as requested):
super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
return;
}
LeakCanary.install(this);
// First Fabric invocation
Fabric.with(this, new Crashlytics.Builder().core(
new CrashlyticsCore.Builder().disabled(true).build()).build());
RxJavaPlugins.setErrorHandler(e -> LOGGER.error("Undeliverable RxJava error", e));
// First Firebase invocation
FirebaseDatabase db = FirebaseDatabase.getInstance();
if (BuildConfig.DEBUG) {
db.setLogLevel(com.google.firebase.database.Logger.Level.DEBUG);
}
db.setPersistenceEnabled(true);
according to mike answer, im add my code:
Gradle:
buildTypes {
release {
manifestPlaceholders = [crashlyticsEnabled: true]
}
debug {
manifestPlaceholders = [crashlyticsEnabled: false]
}
}
Manifest.xml:
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="${crashlyticsEnabled}" />
Mike from Fabric here. Use:
<meta-data android:name="firebase_crashlytics_collection_enabled" android:value="false" />
if you want to disable Crashlytics while using Firebase.
Along with mikes above answer,
If you are setting firebase crash properties somewhere in your code, make sure that you don't set them for debug code, otherwise you might notice strange behaviour for the app.
if (!BuildConfig.DEBUG) {
Crashlytics.setUserIdentifier(DataStore.storeId)
}

Resources