Search code examples
firebasefluttergoogle-cloud-logging

Cloud Logging in Flutter


I want to use Cloud Logging in Flutter mobile app. Also, I will link the Cloud Logging with Firebase.

Is there any way to help me to use Cloud Logging in Flutter?


Solution

  • My solution looks like this: create a service account that can access only logging. I created a service account named logger, and added "logs writer" permission. It contains only the ability to write logs: enter image description here

    Add the service account key as logger.json in the assets folder.

    Then the following to pubspec.yaml:

    ...
    dependencies:
      flutter:
        sdk: flutter
    ...
      googleapis: ^9.2.0
      googleapis_auth: ^1.3.1
    ...
    flutter:
    ...
      assets:
        - logger.json
    ...
    

    Then a minimal working example:

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:googleapis/logging/v2.dart';
    import 'package:googleapis_auth/auth_io.dart';
    
    late final LoggingApi logger;
    
    Future<void> logEvent(String descr) async {
      final Map<String, String> params = {'message': descr};
      final logEntry = LogEntry(
          logName: 'projects/<project-id>/logs/test-log',
          jsonPayload: params,
          resource: MonitoredResource(type: 'global'),
          labels: {'isWeb': '0'});
      final req = WriteLogEntriesRequest(entries: [logEntry]);
      logger.entries.write(req);
    }
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      final f = await rootBundle.loadString('assets/logger.json');
      AutoRefreshingAuthClient httpClient = await clientViaServiceAccount(
          ServiceAccountCredentials.fromJson(String.fromCharCodes(f.codeUnits)), [
        LoggingApi.loggingWriteScope,
      ]);
    
      logger = LoggingApi(httpClient);
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
      @override
      Widget build(BuildContext context) => const MaterialApp(home: MyHomePage());
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key});
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
    
      void _incrementCounter() {
        logEvent('test log no. $_counter');
        setState(() => _counter++);
      }
    
      @override
      Widget build(BuildContext context) => Scaffold(
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  const Text('You have pushed the button this many times:'),
                  Text(
                    '$_counter',
                    style: Theme.of(context).textTheme.headline4,
                  ),
                ],
              ),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: _incrementCounter,
              tooltip: 'Increment',
              child: const Icon(Icons.add),
            ),
          );
    }
    

    In general, adding a service account as an asset is considered unsafe. But since this can only write log entries, it doesn't matter that much I guess. You may consider encoding it, or adding it to storage with the right permission rules.