Firebase crashlytics is not reporting anything on Flutter - flutter

I've initialized and configured Firebase for my Flutter project using this documentation and the instructions given by the Firebase Console. After that, I followed this crashlytics documentation for adding crashlytics to my app. But no matter what I've tried, I couldn't see any reports on the Firebase console. Still seeing this;
My main function looks like this:
Future main() async {
runZonedGuarded(
() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
runApp(const App());
},
(error, stack) async {
await FirebaseCrashlytics.instance.recordError(error, stack);
},
);
}
I've tried to;
crash my app using FirebaseCrashlytics.instance.crash()
throw an exception and record it by the onError callback of the runZonedGuarded
manually record an exception using FirebaseCrashlytics.recordError(error, stack)
setting fatal: true or using FirebaseCrashlytics.instance.recordFlutterFatalError
Is there something that I'm missing? I'm really stuck at this point.

Related

Flutter/Firebase: Need to provide options, when not being deployed to hosting via source

I have an app that runs fine on Android, but when I try to start it for Flutter Web, I get
Uncaught (in promise) Error: [core/no-options] Firebase: Need to provide options, when not being deployed to hosting via source.. The stack trace doesn't go far enough back to point to a spot in my code.
void main() async {
await WidgetsFlutterBinding.ensureInitialized(); // I've tried moving this after
await Firebase.initializeApp(
name: "---",
options: FirebaseOptions(
apiKey: DefaultFirebaseOptions.currentPlatform.apiKey,
appId: DefaultFirebaseOptions.currentPlatform.appId,
messagingSenderId: DefaultFirebaseOptions.currentPlatform.messagingSenderId,
projectId: DefaultFirebaseOptions.currentPlatform.projectId),
);
runApp(const MyApp());
}
If I remove initializeApp(), the app starts to load, and I get a different ear for Firebase not being configured.
if I wrap delay it, like so, it delays the error for 5 seconds, so it's definitely this line
void main() async {
await WidgetsFlutterBinding.ensureInitialized();
await Future.delayed(Duration(seconds: 5), () async {
await Firebase.initializeApp(
name: "---",
options: FirebaseOptions(
apiKey: DefaultFirebaseOptions.currentPlatform.apiKey,
appId: DefaultFirebaseOptions.currentPlatform.appId,
messagingSenderId: DefaultFirebaseOptions.currentPlatform.messagingSenderId,
projectId: DefaultFirebaseOptions.currentPlatform.projectId),
);
});
await Future.delayed(Duration(seconds: 5), () async {
runApp(const MyApp());
});
}
The solution for me was to remove the name Attribute. Apparently it's a recurring bug in the package.
https://github.com/firebase/flutterfire/issues/10228
I just ran the example in FlutterFire - FirebaseCore/Example. This
works just fine!
I narrowed down the issue to the following: Our application works just
fine when I remove the name parameter from the initialization call.
However when I add this I get the error message from above.
Looks to me like somewhere in firebase_auth_web.dart it defaults to
the default app.

flutter FCM subscribe to a topic doesn't seem to work

I implemented FCM successfully. When i send a message from firebase console it comes to the emulator as well. But when i subscribe to a topic it doesn't filter any of the messages. It doesn't matter what i write to channel on firebase console, it comes anyway. Here is my main method.
Here is my main method:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await FirebaseMessaging.instance
.subscribeToTopic('Herkes');
SharedPreferences.getInstance().then((prefs) {
runApp(
ChangeNotifierProvider<ThemeNotifier>(
create: (_) => ThemeNotifier(prefs.getString('theme')),
child: MyApp(),
),
);
});
}
And my console logs after any message come:
W/FirebaseMessaging( 4985): Notification Channel requested (Public2) has not been created by the app. Manifest configuration, or default, value will be used.
W/FirebaseMessaging( 4985): Notification Channel set in AndroidManifest.xml has not been created by the app. Default value will be used.
As in the official docs, you need to add the following metadata element in your AndroidManifest.xml within the application component:
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id"/>

Flutter tests - Having two Integration tests in a same group ()

I'm trying to run two tests in a same group in one test file.
If I split them into two separate test files, they are working fine.
But if I add them in a group, the 2nd test fail with the error saying "TypeAdapter is already registered for the given id".
My app uses HiveDB and it sets up Hive boxes in the main.dart before launching the App. I understand that the 2nd test is also trying the same and fails because the setup is already done.
I followed this doc to setup and write integration tests.
Most of the youtube tutorials, medium articles, and other online resources explain so well on how to run one single test in a test file and they're outdated. I never found a resource having two tests in the same file yet.
Here's my main.dart
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await HiveDB.setup();
runApp(App());
}
test_driver/integration_test.dart
import 'package:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver();
test/app_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:integrationtestdemo/main.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('Home screen tests', () {
tearDown(() async {
print("TearDown() -- called");
await HiveDB.close();
});
testWidgets('Scenario # - loreum ipsum ...', (tester) async {
// ARRANGE
await app.main();
await tester.pumpAndSettle();
// ACT
// ASSERT
expect(1 + 3, 4);
});
testWidgets('Scenario #2', (tester) async {
// ARRANGE
await app.main();
await tester.pumpAndSettle();
// ACT
// ASSERT
expect(2 + 2, 4);
});
});
}
The command I use to execute tests:
flutter drive --driver=.\test_driver\integration_test.dart --target=.\test\app_test.dart
Error I get:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞═════════════════
The following HiveError was thrown running a test:
There is already a TypeAdapter for typeId 1.
When the exception was thrown, this was the stack:
#0 TypeRegistryImpl.registerAdapter (package:hive/src/registry/type_registry_impl.dart:104:11)
#1 HiveDB.setup (package:occasionly/src/services/hive_db.dart:80:10)
<asynchronous suspension>
Could someone please help me here? I'm stuck on this for a long time and couldn't figure out a way to isolate the state between tests?
I have found a dirty trick to solve "TypeAdapter is already registered for the given id" this error
try to put it like this, and the error will not appear anymore
Hive.registerAdapter(YourAdapter(), override: true);
But I have no idea what is the possible impact could this argument do
I also faced the same issue, but I found a workaround by referring to this ERROR in flutter: widget_test.dart cannot detect MyApp(), you could try it.
testWidgets('Scenario #1', (tester) async {
// ARRANGE
await app.main();
...
});
testWidgets('Scenario #2', (tester) async {
// ARRANGE
await tester.pumpWidget(MyApp());
});

Handeling and reporting errors that thrown inside runZonedGuarded callback [Crashlytics, Flutter]

I am implementing Crashlytics with flutter,
and following this docs Using Firebase Crashlytics
I was wondering what would actually happen if an error is thrown inside runZonedGuarded's
error callback: (see the arrow in the code)
void main() async {
runZonedGuarded<Future<void>>(() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
runApp(MyApp());
}, (error, stackTrace) async {
***** some buggy code here ******. <----------
await crashlytics.handleNonFlutterErrors(error,stackTrace);
});;
}
so I have tried it, and to my surprise it is still swallowed by flutter framework and stacktrace was dumped to console - I was expecting the app to crash but it didn't...
does any-body knows how to handle this types of errors?

Getting null argument while routing through firebase push notifications flutter

I am trying to route to a certain screen with some argument when clicked on push notifications. So far it is working fine when app is in foreground or in background but open. But when the app is terminated it is routing to the correct screen but there is some issue with the argument, it is null.
const payload = admin.messaging.MessagingPayload = {
data : {
'type' : 'msg',
'route' : 'chat-screen',
'argument' : sentby,
},
notification : {
title : senderData.user_name,
body: original.message,
image: notificationIcon,
android_channel_id : "Finiso",
channel_id : "Finiso",
clickAction : 'FLUTTER_NOTIFICATION_CLICK',
}
}
This is the code for the notification which I am triggering through cloud functions.
Future<void> backgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print(message.data.toString());
print(message.notification.title);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
added this in main.dart
FirebaseMessaging.instance.getInitialMessage().then((message) async {
if (message != null) {
print(message.data);
routeNotification(message);
}
});
listening to messages and on app open trigger.
void routeNotification(RemoteMessage message) {
final routeName = message.data['route'];
if (routeName == ActivityFeed.routeName) {
Navigator.of(context).pushNamed(ActivityFeed.routeName);
} else {
if (message.data['type'] == 'msg') {
Navigator.pushNamed(
context,
message.data['route'],
arguments: message.data['argument'],
);
}
}
}
This is the routing function I used above
Image showing console logs
It is printing the first two lines from main.dart and "null" is the argument I am trying to get.
Can anyone help me on this. I have no idea what's going on.
Thank you in advance.
I have an answer but I'm not positive on the reason why this is happening yet. Let's collaborate on this.
First of all, I think the routing is happening automatically for you. In all other scenarios except the terminal state, you are pushing the route and handling adding the arguments. In the terminal state, the app is ignoring your initialRoute and using the route from your push notification.
Usually when you setup MaterialApp your initialRoute is used:
MaterialRoute(
initialRoute: '/whatever_you_put_here'
...
)
It seems that WidgetsBinding.instance.platformDispatcher.defaultRouteName (source) is being set within the flutter code and this is causing your default route to be this route instead of whatever you are passing to MaterialApp.
Reading the flutter documentation, it looks like this property is only set when someone calls FlutterView.setInitialRoute from Android.
That is the answer to your question.
--
I don't know what is calling FlutterView.setInitialRoute. A search of FlutterFire code seems to show no instances.