Skip to main content

Get Comment Reaction Data

Retrieve comprehensive reaction data for comments including user reactions, reaction counts, and reaction types. Essential for building engaging social features with detailed interaction analytics and personalized user experiences.

Architecture Overview

User Reactions

Track individual user reactions with myReactions property

All Reactions

Access complete reaction data with reactions property

Reaction Counts

Get total and per-type reaction counts instantly

Real-time Updates

Live reaction data that updates automatically

Key Features

  • Personal Reaction Tracking: myReactions property for user-specific reaction data
  • Complete Reaction List: reactions property for all reactions on a comment
  • Reaction Analytics: reactionsCount for total and categorized counts
  • Real-time Updates: Live data that updates when reactions change
  • Multi-platform Support: Consistent API across all platforms

Reaction Data Properties

PropertyTypeDescription
myReactionsArray<Reaction>Reactions made by the current user
reactionsArray<Reaction>All reactions on the comment
reactionsCountNumberTotal count of all reactions
reactionsSummaryObjectCount breakdown by reaction type

Implementation Guide

Accessing Reaction Data

  • iOS
  • Android
  • TypeScript
  • Flutter
// Get comment with reaction data
SocialPlus.shared.getComment(commentId: "comment_123") { result in
    switch result {
    case .success(let comment):
        // User's own reactions
        let myReactions = comment.myReactions
        print("My reactions: \(myReactions)")
        
        // All reactions on the comment
        let allReactions = comment.reactions
        print("Total reactions: \(allReactions.count)")
        
        // Reaction count
        let count = comment.reactionsCount
        print("Reaction count: \(count)")
        
        // Process reactions
        processReactionData(comment)
        
    case .failure(let error):
        handleError(error)
    }
}

Advanced Reaction Analytics

Generate detailed analytics and insights from reaction data.
interface ReactionAnalytics {
    totalReactions: number;
    reactionBreakdown: Record<string, number>;
    topReaction: string;
    userEngagement: {
        hasReacted: boolean;
        reactionTypes: string[];
    };
    trends: {
        recentActivity: number;
        popularityScore: number;
    };
}

function analyzeReactions(comment: Comment): ReactionAnalytics {
    const reactionBreakdown = comment.reactions.reduce((acc, reaction) => {
        acc[reaction.reactionName] = (acc[reaction.reactionName] || 0) + 1;
        return acc;
    }, {} as Record<string, number>);

    const topReaction = Object.entries(reactionBreakdown)
        .sort(([,a], [,b]) => b - a)[0]?.[0] || '';

    return {
        totalReactions: comment.reactionsCount,
        reactionBreakdown,
        topReaction,
        userEngagement: {
            hasReacted: comment.myReactions.length > 0,
            reactionTypes: comment.myReactions.map(r => r.reactionName)
        },
        trends: {
            recentActivity: calculateRecentActivity(comment.reactions),
            popularityScore: calculatePopularityScore(comment)
        }
    };
}
Create leaderboards based on reaction data.
struct ReactionLeaderboard {
    let topReactors: [String] // User IDs
    let mostPopularReaction: String
    let engagementScore: Double
}

func generateReactionLeaderboard(_ comment: AmityComment) -> ReactionLeaderboard {
    // Count reactions per user
    let userReactionCounts = Dictionary(grouping: comment.reactions) { $0.userId }
        .mapValues { $0.count }
    
    let topReactors = userReactionCounts
        .sorted { $0.value > $1.value }
        .prefix(10)
        .map { $0.key }
    
    // Find most popular reaction
    let reactionCounts = Dictionary(grouping: comment.reactions) { $0.reactionName }
        .mapValues { $0.count }
    
    let mostPopularReaction = reactionCounts
        .sorted { $0.value > $1.value }
        .first?.key ?? ""
    
    // Calculate engagement score
    let engagementScore = Double(comment.reactionsCount) / max(1.0, Double(comment.viewCount ?? 1))
    
    return ReactionLeaderboard(
        topReactors: Array(topReactors),
        mostPopularReaction: mostPopularReaction,
        engagementScore: engagementScore
    )
}
Aggregate reaction data across multiple comments in real-time.
class ReactionAggregator {
    private val reactionData = mutableMapOf<String, ReactionStats>()
    
    data class ReactionStats(
        val totalReactions: Int,
        val reactionBreakdown: Map<String, Int>,
        val userReactions: List<String>
    )
    
    fun aggregateCommentReactions(comments: List<AmityComment>) {
        comments.forEach { comment ->
            val stats = ReactionStats(
                totalReactions = comment.reactionsCount,
                reactionBreakdown = comment.reactions.groupBy { it.reactionName }
                    .mapValues { it.value.size },
                userReactions = comment.myReactions.map { it.reactionName }
            )
            
            reactionData[comment.commentId] = stats
        }
        
        // Notify observers of aggregated data
        notifyReactionDataUpdated()
    }
    
    fun getOverallReactionStats(): ReactionStats {
        val totalReactions = reactionData.values.sumOf { it.totalReactions }
        val overallBreakdown = mutableMapOf<String, Int>()
        val allUserReactions = mutableSetOf<String>()
        
        reactionData.values.forEach { stats ->
            stats.reactionBreakdown.forEach { (type, count) ->
                overallBreakdown[type] = (overallBreakdown[type] ?: 0) + count
            }
            allUserReactions.addAll(stats.userReactions)
        }
        
        return ReactionStats(
            totalReactions = totalReactions,
            reactionBreakdown = overallBreakdown,
            userReactions = allUserReactions.toList()
        )
    }
}

Best Practices

Performance Optimization

  • Cache reaction data to reduce API calls
  • Use pagination for large reaction lists
  • Implement efficient diff algorithms for UI updates
  • Batch reaction data requests when possible

Real-time Updates

  • Listen to live object changes for instant updates
  • Handle reaction additions/removals gracefully
  • Implement optimistic UI updates for better UX
  • Use debouncing for rapid reaction changes

User Experience

  • Show visual feedback for user’s own reactions
  • Implement smooth animations for reaction changes
  • Display popular reactions prominently
  • Provide reaction analytics and insights

Data Management

  • Normalize reaction data for efficient storage
  • Implement proper error handling for missing data
  • Use consistent reaction type naming conventions
  • Handle edge cases like deleted reactions

Reaction Data Structure

interface Reaction {
    reactionId: string;
    reactionName: string; // "like", "love", "laugh", "angry", etc.
    userId: string;
    createdAt: Date;
    updatedAt: Date;
}

interface Comment {
    commentId: string;
    // ...other comment properties
    myReactions: Reaction[];      // Current user's reactions
    reactions: Reaction[];        // All reactions on the comment
    reactionsCount: number;       // Total reaction count
    reactionsSummary: {           // Count by reaction type
        [reactionType: string]: number;
    };
}

Error Handling

Error TypeDescriptionRecommended Action
REACTION_NOT_FOUNDReaction data unavailableShow fallback UI state
PERMISSION_DENIEDUser cannot view reactionsHandle authentication
NETWORK_ERRORConnection issuesImplement retry logic
RATE_LIMITEDToo many reaction requestsUse exponential backoff
INVALID_REACTION_TYPEUnknown reaction typeFilter or handle gracefully

Use Cases

Build an engaging comment feed with rich reaction displays.
interface CommentFeedItem {
    comment: Comment;
    reactionAnalytics: ReactionAnalytics;
    userInteraction: {
        hasReacted: boolean;
        canReact: boolean;
        reactionTypes: string[];
    };
}

class CommentFeed {
    async loadCommentsWithReactions(postId: string): Promise<CommentFeedItem[]> {
        const comments = await SocialPlus.queryComments(postId);
        
        return comments.map(comment => ({
            comment,
            reactionAnalytics: this.analyzeReactions(comment),
            userInteraction: {
                hasReacted: comment.myReactions.length > 0,
                canReact: this.canUserReact(comment),
                reactionTypes: comment.myReactions.map(r => r.reactionName)
            }
        }));
    }
}
Create analytics dashboards showing reaction trends and insights.
class ReactionDashboard {
    func generateReactionInsights(for comments: [AmityComment]) -> ReactionInsights {
        let totalReactions = comments.reduce(0) { $0 + $1.reactionsCount }
        let avgReactionsPerComment = Double(totalReactions) / Double(comments.count)
        
        // Most popular reaction types
        let allReactions = comments.flatMap { $0.reactions }
        let reactionTypePopularity = Dictionary(grouping: allReactions) { $0.reactionName }
            .mapValues { $0.count }
            .sorted { $0.value > $1.value }
        
        // User engagement metrics
        let userEngagement = comments.map { comment in
            UserEngagement(
                commentId: comment.commentId,
                reactionCount: comment.reactionsCount,
                userReacted: !comment.myReactions.isEmpty,
                topReaction: reactionTypePopularity.first?.key ?? ""
            )
        }
        
        return ReactionInsights(
            totalReactions: totalReactions,
            averageReactions: avgReactionsPerComment,
            popularReactionTypes: reactionTypePopularity.map { $0.key },
            userEngagement: userEngagement
        )
    }
}
Send notifications based on reaction patterns and thresholds.
class ReactionNotificationManager {
    fun checkReactionMilestones(comment: AmityComment) {
        val reactionCount = comment.reactionsCount
        val milestones = listOf(10, 50, 100, 500, 1000)
        
        milestones.forEach { milestone ->
            if (reactionCount == milestone) {
                sendMilestoneNotification(comment, milestone)
            }
        }
        
        // Check for trending reactions
        val recentReactions = comment.reactions.filter { 
            it.createdAt.isAfter(LocalDateTime.now().minusHours(1))
        }
        
        if (recentReactions.size >= 10) {
            sendTrendingNotification(comment, recentReactions.size)
        }
    }
    
    private fun sendMilestoneNotification(comment: AmityComment, milestone: Int) {
        val notification = NotificationBuilder()
            .setTitle("Your comment is popular!")
            .setMessage("Your comment reached $milestone reactions")
            .setAction("VIEW_COMMENT", comment.commentId)
            .build()
            
        notificationService.send(comment.userId, notification)
    }
}
For advanced real-time features, see Real-time Events.