Documentation Index
Fetch the complete documentation index at: https://learn.social.plus/llms.txt
Use this file to discover all available pages before exploring further.
Authentication
Before users can create or view live streams, they need to be authenticated with the social.plus platform. This guide covers authentication setup for video features across all platforms.
Authentication Flow
The Video SDK uses the same authentication system as the Core SDK:
- User Registration/Login - Authenticate users with your backend
- Session Token - Generate secure session tokens
- SDK Authentication - Use tokens to authenticate with social.plus
- Video Access - Access video features with authenticated session
Prerequisites
- social.plus API credentials configured
- Core SDK installed and initialized
- User management system in place
Android
import com.amity.socialcloud.sdk.core.session.AmitySessionManager
class VideoAuthManager {
fun authenticateUser(userId: String, displayName: String, callback: (Boolean) -> Unit) {
AmitySessionManager.login(userId, displayName)
.subscribe({ user ->
// Authentication successful
Log.d("Auth", "User authenticated: ${user.displayName}")
callback(true)
}, { error ->
// Authentication failed
Log.e("Auth", "Authentication failed: ${error.message}")
callback(false)
})
}
fun logout() {
AmitySessionManager.logout()
.subscribe({
Log.d("Auth", "User logged out successfully")
}, { error ->
Log.e("Auth", "Logout failed: ${error.message}")
})
}
fun getCurrentUser(): AmityUser? {
return AmitySessionManager.getCurrentUser()
}
fun isAuthenticated(): Boolean {
return AmitySessionManager.isLoggedIn()
}
}
iOS
import AmitySDK
class VideoAuthManager {
func authenticateUser(userId: String, displayName: String, completion: @escaping (Bool) -> Void) {
AmityManager.login(userId: userId, displayName: displayName) { [weak self] result in
switch result {
case .success(let user):
print("User authenticated: \(user.displayName ?? "")")
completion(true)
case .failure(let error):
print("Authentication failed: \(error.localizedDescription)")
completion(false)
}
}
}
func logout() {
AmityManager.logout { result in
switch result {
case .success:
print("User logged out successfully")
case .failure(let error):
print("Logout failed: \(error.localizedDescription)")
}
}
}
func getCurrentUser() -> AmityUser? {
return AmityManager.getCurrentUser()
}
func isAuthenticated() -> Bool {
return AmityManager.isLoggedIn()
}
}
Web
import { AmityVideoSDK } from '@amityco/video-sdk';
class VideoAuthManager {
constructor(videoSDK) {
this.videoSDK = videoSDK;
}
async authenticateUser(userId, displayName, authToken = null) {
try {
const user = await this.videoSDK.login(userId, displayName, authToken);
console.log('User authenticated:', user.displayName);
return { success: true, user };
} catch (error) {
console.error('Authentication failed:', error);
return { success: false, error };
}
}
async logout() {
try {
await this.videoSDK.logout();
console.log('User logged out successfully');
return { success: true };
} catch (error) {
console.error('Logout failed:', error);
return { success: false, error };
}
}
getCurrentUser() {
return this.videoSDK.getCurrentUser();
}
isAuthenticated() {
return this.videoSDK.isLoggedIn();
}
}
React Native
import { AmityVideoSDK } from '@amityco/react-native-video-sdk';
class VideoAuthManager {
static async authenticateUser(userId, displayName, authToken = null) {
try {
const user = await AmityVideoSDK.login(userId, displayName, authToken);
console.log('User authenticated:', user.displayName);
return { success: true, user };
} catch (error) {
console.error('Authentication failed:', error);
return { success: false, error };
}
}
static async logout() {
try {
await AmityVideoSDK.logout();
console.log('User logged out successfully');
return { success: true };
} catch (error) {
console.error('Logout failed:', error);
return { success: false, error };
}
}
static getCurrentUser() {
return AmityVideoSDK.getCurrentUser();
}
static isAuthenticated() {
return AmityVideoSDK.isLoggedIn();
}
}
Flutter
import 'package:amity_video_sdk/amity_video_sdk.dart';
class VideoAuthManager {
static Future<Map<String, dynamic>> authenticateUser(
String userId,
String displayName,
[String? authToken]
) async {
try {
final user = await AmityVideoSDK.login(
userId: userId,
displayName: displayName,
authToken: authToken,
);
print('User authenticated: ${user.displayName}');
return {'success': true, 'user': user};
} catch (error) {
print('Authentication failed: $error');
return {'success': false, 'error': error};
}
}
static Future<Map<String, dynamic>> logout() async {
try {
await AmityVideoSDK.logout();
print('User logged out successfully');
return {'success': true};
} catch (error) {
print('Logout failed: $error');
return {'success': false, 'error': error};
}
}
static Future<AmityUser?> getCurrentUser() async {
return await AmityVideoSDK.getCurrentUser();
}
static Future<bool> isAuthenticated() async {
return await AmityVideoSDK.isLoggedIn();
}
}
TypeScript React Native
import { StreamRepository } from '@amityco/ts-sdk-react-native';
interface AuthResult {
success: boolean;
user?: any;
error?: Error;
}
class VideoAuthManager {
static async authenticateUser(
userId: string,
displayName: string,
authToken?: string
): Promise<AuthResult> {
try {
// Authentication handled by core SDK
// Video features available after authentication
const user = await StreamRepository.authenticateUser(userId, displayName, authToken);
console.log('User authenticated:', user.displayName);
return { success: true, user };
} catch (error) {
console.error('Authentication failed:', error);
return { success: false, error: error as Error };
}
}
static async logout(): Promise<AuthResult> {
try {
await StreamRepository.logout();
console.log('User logged out successfully');
return { success: true };
} catch (error) {
console.error('Logout failed:', error);
return { success: false, error: error as Error };
}
}
}
Authentication Best Practices
Secure Token Management
Never hardcode API keys or tokens in client-side code
// ❌ Don't do this
const apiKey = 'your-api-key-here';
// ✅ Do this instead
const apiKey = process.env.REACT_APP_SOCIAL_PLUS_API_KEY;
Token Refresh
Handle token expiration gracefully:
class TokenManager {
constructor(videoSDK) {
this.videoSDK = videoSDK;
this.refreshTimer = null;
}
async refreshToken() {
try {
const newToken = await this.getTokenFromBackend();
await this.videoSDK.updateToken(newToken);
this.scheduleTokenRefresh();
} catch (error) {
console.error('Token refresh failed:', error);
this.handleAuthError();
}
}
scheduleTokenRefresh() {
// Refresh token before it expires
const refreshInterval = 45 * 60 * 1000; // 45 minutes
this.refreshTimer = setTimeout(() => {
this.refreshToken();
}, refreshInterval);
}
handleAuthError() {
// Redirect to login or show auth error
this.videoSDK.logout();
}
}
User Session Management
Track user authentication state:
class SessionManager {
constructor() {
this.user = null;
this.isAuthenticated = false;
this.listeners = [];
}
addListener(listener) {
this.listeners.push(listener);
}
removeListener(listener) {
this.listeners = this.listeners.filter(l => l !== listener);
}
notifyListeners(event, data) {
this.listeners.forEach(listener => listener(event, data));
}
async login(userId, displayName) {
try {
const result = await VideoAuthManager.authenticateUser(userId, displayName);
if (result.success) {
this.user = result.user;
this.isAuthenticated = true;
this.notifyListeners('login', this.user);
}
return result;
} catch (error) {
this.notifyListeners('login_error', error);
throw error;
}
}
async logout() {
try {
await VideoAuthManager.logout();
this.user = null;
this.isAuthenticated = false;
this.notifyListeners('logout', null);
} catch (error) {
this.notifyListeners('logout_error', error);
throw error;
}
}
}
Testing Authentication
Verify Authentication State
Create a simple test to verify authentication:
// Test authentication flow
const testAuth = async () => {
const testUserId = 'test-user-123';
const testDisplayName = 'Test User';
try {
// Test login
const loginResult = await VideoAuthManager.authenticateUser(
testUserId,
testDisplayName
);
if (loginResult.success) {
console.log('✅ Login successful');
// Test getting current user
const currentUser = VideoAuthManager.getCurrentUser();
console.log('✅ Current user:', currentUser?.displayName);
// Test authentication check
const isAuth = VideoAuthManager.isAuthenticated();
console.log('✅ Is authenticated:', isAuth);
// Test logout
const logoutResult = await VideoAuthManager.logout();
console.log('✅ Logout successful:', logoutResult.success);
} else {
console.error('❌ Login failed:', loginResult.error);
}
} catch (error) {
console.error('❌ Authentication test failed:', error);
}
};
Error Handling
Common Authentication Errors
const handleAuthError = (error) => {
switch (error.code) {
case 'INVALID_API_KEY':
console.error('Invalid API key provided');
break;
case 'USER_NOT_FOUND':
console.error('User not found or invalid user ID');
break;
case 'TOKEN_EXPIRED':
console.error('Authentication token expired');
// Trigger token refresh
break;
case 'NETWORK_ERROR':
console.error('Network error during authentication');
// Retry authentication
break;
case 'PERMISSION_DENIED':
console.error('Insufficient permissions for video features');
break;
default:
console.error('Unknown authentication error:', error);
}
};
Next Steps
With authentication configured:
- Create Your First Stream - Build basic streaming functionality
- Core Concepts - Understand streaming fundamentals
- Broadcasting Setup - Configure advanced streaming features
Security Considerations
- Always validate user permissions on your backend
- Use secure token storage (Keychain on iOS, KeyStore on Android)
- Implement proper session timeout handling
- Monitor authentication failures for security threats
- Use HTTPS for all authentication requests
Important: Video features require an authenticated user session. Ensure authentication is complete before attempting to create or view streams.