admin管理员组

文章数量:1319487

Here two questions:

  1. what can be the reasons for this mentioned error in screenshot?
  2. Why does it always show the same Title (Google IO) even though I changed my code? It never changes to any other info? Any way to modify it?

Code (tried with "it" or "en" or "en-US" but it gives error for devices where language is set to it.):

import 'dart:convert';

import 'package:google_wallet_app/main.dart';
import 'package:jose/jose.dart';
import 'package:uuid/uuid.dart';
import 'package:http/http.dart' as http;

class BadgeGenerator {
  static const String baseUrl = '';
  static const String issuerId = '3388000000000000000';
  static const String className = 'test';
  static const String cardTitle = 'Test';
  static const String defaultLang = 'en';

  // Add a static variable to track class creation
  static bool _isClassCreated = false;

  static Future<String> generateBadge(
      Map<String, String> user, Map<String, dynamic> clientSecret) async {
    String issuerEmail = clientSecret['client_email'];
    String privateKey = clientSecret['private_key'];
    final passId = const Uuid().v4();

    final gruppo = user['gruppo'];
    final codFiscale = user['cod_fiscale'];
    final email = user['email'];
    final nome = user['name'];
    final cognome = user['surname'];

    final classId = '$issuerId.$className';
    final objectId = '$issuerId.${email?.replaceAll(RegExp(r'[^\w.-]'), '_')}';
    logger.i('Generated Object ID: $objectId');

    // Check and create class if needed
    if (!_isClassCreated) {
      logger.i('Class not created, creating...');
      await _createClassIfNotExists(classId, clientSecret);
      _isClassCreated = true; // Mark as created
    }

    // Create badge object
    final badgeObject = {
      'id': objectId,
      'classId': classId,
      "logo": {
        "sourceUri": {
          "uri":
              ".jpg",
        },
        "contentDescription": {
          "defaultValue": {
            "language": defaultLang,
            "value": "LOGO_IMAGE_DESCRIPTION",
          },
        },
      },
      'hexBackgroundColor': '#4285f4',
      'cardTitle': {
        'defaultValue': {"language": defaultLang, 'value': cardTitle}
      },
      'subheader': {
        'defaultValue': {"language": defaultLang, 'value': gruppo}
      },
      'header': {
        'defaultValue': {"language": defaultLang, 'value': '$nome $cognome'}
      },
      "textModulesData": [
        {
          "id": "group",
          "header": "GROUP",
          "body": gruppo,
        },
        {
          "id": "cod_fiscale",
          "header": "COD FISCALE",
          "body": codFiscale,
        },
      ],
      'barcode': {'type': 'QR_CODE', 'value': "$email"},
    };

    // Create JWT payload
    final payload = {
      "iss": issuerEmail,
      "aud": "google",
      "typ": "savetowallet",
      "payload": {
        "genericObjects": [badgeObject],
      },
    };

    // Sign the JWT and generate the Google Wallet link
    final jwt = JsonWebSignatureBuilder()
      ..jsonContent = payload
      ..addRecipient(JsonWebKey.fromPem(privateKey), algorithm: "RS256");

    final token = jwt.build().toCompactSerialization();

    // Generate the Save to Wallet URL
    final saveUrl = '/$token';
    return saveUrl;
  }

  static Future<void> _createClassIfNotExists(
      String classId, Map<String, dynamic> clientSecret) async {
    final credentials = clientSecret['private_key'];
    final httpClient = http.Client();

    try {
      // Check if the class exists
      final response = await httpClient.get(
        Uri.parse('$baseUrl/genericClass/$classId'),
        headers: {
          'Authorization': 'Bearer ${_generateAccessToken(clientSecret)}',
          'Content-Type': 'application/json',
        },
      );

      if (response.statusCode == 404) {
        // Create class if it doesn't exist
        final genericClass = {
          'id': classId,
          "classTemplateInfo": {
            "cardTemplateOverride": {
              "cardRowTemplateInfos": [
                {
                  "twoItems": {
                    "startItem": {
                      "firstValue": {
                        "fields": [
                          {
                            "fieldPath": "object.textModulesData['group']",
                          },
                        ],
                      },
                    },
                    "endItem": {
                      "firstValue": {
                        "fields": [
                          {
                            "fieldPath": "object.textModulesData['cod_fiscale']",
                          },
                        ],
                      },
                    },
                  },
                },
              ],
            },
          }
        };

        final res = await httpClient.post(
          Uri.parse('$baseUrl/genericClass'),
          headers: {
            'Authorization': 'Bearer ${_generateAccessToken(clientSecret)}',
            'Content-Type': 'application/json',
          },
          body: jsonEncode(genericClass),
        );
        logger.i('Class created | ${res.statusCode} | ${res.body}');
      }
    } finally {
      httpClient.close();
    }
  }

  static String _generateAccessToken(Map<String, dynamic> clientSecret) {
    // Generate an access token (JWT) using clientSecret
    final now = DateTime.now().millisecondsSinceEpoch ~/ 1000;
    final exp = now + 3600; // 1 hour expiration

    final payload = {
      'iss': clientSecret['client_email'],
      'sub': clientSecret['client_email'],
      'aud': '/',
      'iat': now,
      'exp': exp,
      'scope': '.issuer',
    };

    final jwt = JsonWebSignatureBuilder()
      ..jsonContent = payload
      ..addRecipient(JsonWebKey.fromPem(clientSecret['private_key']), algorithm: 'RS256');

    return jwt.build().toCompactSerialization();
  }
}

本文标签: nodejsGoogle Wallet showing Default Value of Localized String cannot be emptyStack Overflow