flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

[firebase_analytics]: [iOS] Hashed phone number is not 32 bytes

Open gilnobrega-tide opened this issue 1 month ago • 0 comments

Is there an existing issue for this?

  • [x] I have searched the existing issues.

Which plugins are affected?

Analytics

Which platforms are affected?

iOS

Description

The native FirebaseAnalytics initiateOnDeviceConversionMeasurement method expects hashes that are 32 bytes long

Note that the hashed SHA256 email or phone numbers must be 32 bytes long and not a hexadecimal string.

However, it looks like these hashes are not decoded correctly in firebase_analytics Flutter package. The Swift plugin implementation uses UTF8 for decoding the string representation of this hash that comes from the Flutter layer, resulting in hashed data that is longer than 32 bytes. https://github.com/firebase/flutterfire/blob/455a068773239ec9a6d42cfe52b10ee973bbfedb/packages/firebase_analytics/firebase_analytics/ios/firebase_analytics/Sources/firebase_analytics/FirebaseAnalyticsPlugin.swift#L139

It is possible to observe logs in XCode with this error

11.6.0 - [FirebaseAnalytics][I-ACS025057] Hashed phone number should be 32 bytes (256 bits)

Reproducing the issue

Create Flutter project with iOS Add the following launch parameters in XCode: -DebugOnDeviceConversionMeasurement and -FIRDebugEnabled Follow guide for setting up firebase environment https://firebase.google.com/docs/flutter/setup?platform=ios

main.dart
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_issue/firebase_options.dart';
import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  void _runTest() {
    // 1. Define input
    const internationalPhoneNumber = "+14155552671";
    print('Input phone number: $internationalPhoneNumber');

    // 2. Hash the number
    final bytes = utf8.encode(internationalPhoneNumber);
    final hashBytes = sha256.convert(bytes).bytes;
    print('Generated hash has ${hashBytes.length} bytes.'); // EXPECTED: 32

    // 3. Encode using utf8
    final hashedPhoneNumberString = utf8.decode(
      hashBytes,
      allowMalformed: true,
    );
    print(
      'utf8 string length: ${hashedPhoneNumberString.length} chars.',
    );

    // 4. Call the Firebase API
    print('Calling Firebase with the utf8 encoded string...');
    FirebaseAnalytics.instance
        .initiateOnDeviceConversionMeasurementWithHashedPhoneNumber(
          hashedPhoneNumberString,
        );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: ElevatedButton(
            onPressed: _runTest,
            child: const Text('Run ODC Measurement Test'),
          ),
        ),
      ),
    );
  }
}
dependencies in pubspec.yaml

cupertino_icons: ^1.0.8 firebase_analytics: ^12.0.3 firebase_core: ^4.2.0 crypto: ^3.0.6

Logs in XCode: Image

Firebase Core version

4.2.0

Flutter Version

3.35.4

Relevant Log Output


Flutter dependencies

Expand Flutter dependencies snippet
- firebase_core_web 3.2.0 [firebase_core_platform_interface flutter flutter_web_plugins meta web]
- flutter_web_plugins 0.0.0 [flutter]
- leak_tracker 11.0.2 [clock collection meta path vm_service]
- leak_tracker_flutter_testing 3.0.10 [flutter leak_tracker leak_tracker_testing matcher meta]
- leak_tracker_testing 3.0.2 [leak_tracker matcher meta]
- lints 5.1.1
- matcher 0.12.17 [async meta stack_trace term_glyph test_api]
- material_color_utilities 0.11.1 [collection]
- meta 1.16.0
- path 1.9.1
- plugin_platform_interface 2.1.8 [meta]
- sky_engine 0.0.0
- source_span 1.10.1 [collection path term_glyph]
- stack_trace 1.12.1 [path]
- stream_channel 2.1.4 [async]
- string_scanner 1.4.1 [source_span]
- term_glyph 1.2.2
- test_api 0.7.6 [async boolean_selector collection meta source_span stack_trace stream_channel string_scanner term_glyph]
- typed_data 1.4.0 [collection]
- vector_math 2.2.0
- vm_service 15.0.2
- web 1.1.1

Additional context and comments

No response

gilnobrega-tide avatar Oct 14 '25 11:10 gilnobrega-tide