Skip to main content

Integrations

Grove integrates with various external services to provide authentication, notifications, and future capabilities. This document details all current and planned integrations.

Integration Architecture


Current Integrations

1. Google Sign-In

Purpose: Allow users to authenticate using their Google account for quick, secure access.

Configuration:

PlatformRequirement
iOSGoogle OAuth client ID (iOS type)
AndroidGoogle OAuth client ID (Android type)
WebGoogle OAuth client ID (Web type)

Implementation:

// Using expo-auth-session
import * as Google from 'expo-auth-session/providers/google';

const [request, response, promptAsync] = Google.useAuthRequest({
iosClientId: process.env.EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID,
androidClientId: process.env.EXPO_PUBLIC_GOOGLE_ANDROID_CLIENT_ID,
});

const handleGoogleSignIn = async () => {
const result = await promptAsync();
if (result?.type === 'success') {
const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'google',
token: result.authentication.idToken,
});
}
};

Scopes Requested:

  • openid - Basic identity
  • email - User's email address
  • profile - User's name and photo

2. Apple Sign-In

Purpose: Provide native Apple authentication on iOS devices, required for App Store compliance.

Configuration:

RequirementDescription
Apple Developer AccountRequired ($99/year)
App ID with Sign In capabilityEnable in developer portal
Service IDFor web-based Apple Sign-In

Implementation:

import * as AppleAuthentication from 'expo-apple-authentication';

const handleAppleSignIn = async () => {
const credential = await AppleAuthentication.signInAsync({
requestedScopes: [
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
AppleAuthentication.AppleAuthenticationScope.EMAIL,
],
});

const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'apple',
token: credential.identityToken,
});
};

Privacy Features:

  • Hide My Email support
  • User can share or hide real email
  • Name only provided on first sign-in

3. Push Notifications (Expo)

Purpose: Deliver real-time notifications for events, tasks, messages, and community updates.

Notification Types:

TypeTriggerPriority
Event Reminder1 hour before eventHigh
Task AssignedNew task assignmentNormal
New MessageChat message in channelNormal
Join RequestUser requests to joinNormal
Request ApprovedAdmin approves joinHigh
Contribution DuePayment reminderNormal

Implementation:

// Register for push notifications
import * as Notifications from 'expo-notifications';

async function registerForPush() {
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') return;

const token = await Notifications.getExpoPushTokenAsync({
projectId: Constants.expoConfig.extra.eas.projectId,
});

// Store token in database for later use
await supabase.from('push_tokens').upsert({
user_id: userId,
token: token.data,
platform: Platform.OS,
});
}

// Handle incoming notifications
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: true,
}),
});

Push Token Management:


4. Email Notifications (Supabase)

Purpose: Send transactional emails for authentication, invites, and important updates.

Email Types:

Email TypeTriggerTemplate
WelcomeAccount creationOnboarding info
Magic LinkPasswordless loginLogin link
Password ResetReset requestReset link
InviteCommunity inviteJoin link
Event ReminderUpcoming eventEvent details

Supabase Email Configuration:

-- Custom email templates can be set in Supabase Dashboard
-- Authentication > Email Templates

-- Example: Custom invite email
Subject: You're invited to join {{community_name}} on Grove
Body:
Hi {{user_name}},

You've been invited to join {{community_name}} on Grove!

Click here to accept: {{invite_link}}

See you there!

Planned Integrations

1. Calendar Sync

Purpose: Sync Grove events with Google Calendar and Apple Calendar.

Planned Features:

  • Two-way sync for event changes
  • Automatic RSVP from calendar response
  • Calendar availability for event planning
  • Recurring event sync

Implementation Approach:

// Google Calendar (using googleapis)
async function syncToGoogleCalendar(event) {
const calendar = google.calendar({ version: 'v3', auth });

await calendar.events.insert({
calendarId: 'primary',
resource: {
summary: event.title,
description: event.description,
start: { dateTime: event.start_time },
end: { dateTime: event.end_time },
location: event.location,
},
});
}

// Apple Calendar (using expo-calendar)
async function syncToAppleCalendar(event) {
await Calendar.createEventAsync(calendarId, {
title: event.title,
notes: event.description,
startDate: new Date(event.start_time),
endDate: new Date(event.end_time),
location: event.location,
});
}

2. Payment Integration (Stripe)

Purpose: Enable online payments for community contributions and dues.

Planned Features:

  • Stripe Connect for community payouts
  • In-app payment UI
  • Automatic payment splitting
  • Payment history and receipts
  • Refund handling

Phase 2 Scope:

  1. Community admins connect Stripe account
  2. Members pay contributions via card
  3. Automatic settlement marking
  4. Transaction records with Stripe references

3. Analytics Integration

Purpose: Track user behavior, engagement, and app performance.

Planned Platform: PostHog (self-hosted option available)

Key Events to Track:

EventPropertiesPurpose
user_signed_upmethod, sourceAcquisition analysis
community_createdcategory, join_modeActivation tracking
event_createdis_recurring, has_locationFeature usage
message_sentmedia_attachedEngagement metrics
contribution_paidamount, currencyRevenue tracking

Implementation:

import posthog from 'posthog-react-native';

// Initialize
posthog.init(POSTHOG_API_KEY, {
host: POSTHOG_HOST,
});

// Identify user
posthog.identify(userId, {
email: user.email,
name: user.full_name,
created_at: user.created_at,
});

// Track events
posthog.capture('community_created', {
community_id: community.id,
category: community.category,
join_mode: community.join_mode,
});

4. Error Monitoring (Sentry)

Purpose: Track and alert on application errors and crashes.

Implementation:

import * as Sentry from '@sentry/react-native';

Sentry.init({
dsn: SENTRY_DSN,
environment: __DEV__ ? 'development' : 'production',
tracesSampleRate: 0.2,
attachStacktrace: true,
});

// Set user context
Sentry.setUser({
id: userId,
email: user.email,
});

// Capture errors
try {
await riskyOperation();
} catch (error) {
Sentry.captureException(error, {
extra: {
community_id: communityId,
action: 'create_event',
},
});
}

Integration Security

API Key Management

Secret Storage Strategy:

Secret TypeStorageAccess
Public API keysapp.config.jsClient-side
OAuth client IDsEnvironment variablesBuild-time
Service account keysEAS SecretsBuild-time only
User tokensexpo-secure-storeRuntime only

OAuth Security

  • State parameter for CSRF protection
  • PKCE for mobile OAuth flows
  • Token stored in secure storage
  • Short-lived access tokens with refresh

Integration Limits

Current Plan Limits (Supabase Free Tier)

ServiceLimitNotes
API Requests2M/monthSufficient for MVP
Database500 MBMonitor growth
Storage1 GBCompress images
Realtime200 concurrentPer project
Auth MAUs50,000Monthly active

Expo Push Limits

TierNotifications/MonthPriority Support
Free1,000No
ProductionUnlimitedYes

Integration Roadmap


Integration Testing

Test Accounts

ServiceTest ModeNotes
Google OAuthUse test usersAdd in GCP console
Apple Sign-InSandboxUse simulator
StripeTest modeUse test API keys
PushExpo dev clientReal device required

Integration Health Checks

async function checkIntegrations() {
const results = {
supabase: await checkSupabase(),
push: await checkPushPermissions(),
google: await checkGoogleAuth(),
};

return results;
}