Enhancing User Privacy in Contact Syncing


In this guide, we delve into a privacy-centric approach to syncing user contacts in a React Native app. By hashing phone numbers using GoLang and storing them in DynamoDB, we protect the privacy of individuals whose data is being processed without their direct consent. This method is further supported by defining the database schema using Terraform.

The Privacy Challenge and Solution

When users sync their contacts with an application, it involves sensitive data, particularly the phone numbers of their contacts who haven't consented to share their information. To address this, we hash phone numbers before storing them, thus providing an irreversible, secure way to handle this data.

Benefits of Hashing Phone Numbers

  • Irreversible Transformation: Hashing is a one-way process, making it almost impossible to derive the original phone number from the hash.
  • Data Protection: In case of a data breach, hashed numbers offer no immediate value to attackers.
  • Compliance with Data Laws: Hashing aligns with data protection regulations, safeguarding against legal issues.

Frontend: Fetching and Sending Contacts with React Native

We start by fetching contacts in the app and preparing them for synchronization.

Fetching Contacts with Expo-Contacts

 1// React Native code to fetch contacts
 2import * as Contacts from 'expo-contacts';
 4async function fetchContacts() {
 5  const { status } = await Contacts.requestPermissionsAsync();
 6  if (status !== 'granted') {
 7    throw new Error('Permission denied');
 8  }
10  const { data } = await Contacts.getContactsAsync({
11    fields: [Contacts.Fields.PhoneNumbers],
12  });
14  return data.map(contact => ({
15    name: contact.name,
16    phoneNumbers: contact.phoneNumbers.map(number => number.number),
17  }));

Syncing Contacts with the Backend

 1// Code to send contacts to the backend
 2async function syncContacts(contacts) {
 3  await fetch('https://your-api-endpoint.com/user/contacts', {
 4    method: 'POST',
 5    headers: {
 6      'Content-Type': 'application/json',
 7    },
 8    body: JSON.stringify(contacts),
 9  });

Backend: Hashing and Storing Contacts with GoLang and DynamoDB

The backend handles hashing and storage in a DynamoDB table.

Hashing Phone Numbers in GoLang

 1// GoLang code for hashing phone numbers
 2import (
 3  "crypto/sha256"
 4  "encoding/hex"
 7func hashPhoneNumber(phoneNumber string) string {
 8  hasher := sha256.New()
 9  hasher.Write([]byte(phoneNumber))
10  return hex.EncodeToString(hasher.Sum(nil))

Storing Contacts in DynamoDB

1// GoLang code for storing hashed contacts in DynamoDB
2type Contact struct {
3  ContactID string `json:"contact_id"`
4  UserID    string `json:"user_id"`
7// Function to store contact goes here

DynamoDB Schema with Terraform

Here's how the DynamoDB schema can be set up using Terraform.

 1# Terraform configuration for DynamoDB schema
 2resource "aws_dynamodb_table" "contacts_table" {
 3  name           = "ContactsTable"
 4  billing_mode   = "PAY_PER_REQUEST"
 5  hash_key       = "ContactID"
 7  attribute {
 8    name = "ContactID"
 9    type = "S"
10  }
12  attribute {
13    name = "UserID"
14    type = "S"
15  }
17  // Additional configurations...

Use Case: Privacy-Centric Notifications

When a new user joins and their contacts are synced, the hashed phone numbers are checked against those in DynamoDB. If a match is found, existing users are notified that a contact has joined, all while maintaining the privacy of the contacts.


This privacy-centric approach in a contact syncing feature balances functionality with ethical responsibility. By using hashing and secure storage methods, the solution respects the privacy of individuals and complies with data protection laws, thus fostering trust and reliability in the application. This guide demonstrates how technology can be used responsibly to handle sensitive data in today's digital landscape.

Let me know if you find this useful!

comments powered by Disqus