App.js 8.83 KB
Newer Older
renato's avatar
renato committed
1 2 3 4 5 6 7 8 9 10 11
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  TouchableOpacity,
12
  View,
Libin Lu's avatar
Libin Lu committed
13
  Clipboard,
Libin Lu's avatar
Libin Lu committed
14 15
  Platform,
  ScrollView
renato's avatar
renato committed
16 17
} from 'react-native';

Libin Lu's avatar
Libin Lu committed
18 19
import { StackNavigator } from 'react-navigation';

Libin Lu's avatar
Libin Lu committed
20
import FCM, {NotificationActionType} from "react-native-fcm";
Libin Lu's avatar
Libin Lu committed
21

Libin Lu's avatar
Libin Lu committed
22
import {registerKilledListener, registerAppListener} from "./Listeners";
renato's avatar
renato committed
23 24
import firebaseClient from  "./FirebaseClient";

Libin Lu's avatar
Libin Lu committed
25 26
registerKilledListener();

Libin Lu's avatar
Libin Lu committed
27
class MainPage extends Component {
28 29 30 31
  constructor(props) {
    super(props);

    this.state = {
32 33
      token: "",
      tokenCopyFeedback: ""
34 35 36
    }
  }

Libin Lu's avatar
Libin Lu committed
37
  async componentDidMount(){
Libin Lu's avatar
Libin Lu committed
38
    registerAppListener(this.props.navigation);
Libin Lu's avatar
Libin Lu committed
39 40 41 42
    FCM.getInitialNotification().then(notif => {
      this.setState({
        initNotif: notif
      })
Libin Lu's avatar
Libin Lu committed
43
      if(notif && notif.targetScreen === 'detail'){
Libin Lu's avatar
Libin Lu committed
44 45 46 47
        setTimeout(()=>{
          this.props.navigation.navigate('Detail')
        }, 500)
      }
Libin Lu's avatar
Libin Lu committed
48
    });
Libin Lu's avatar
Libin Lu committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

    try{
      let result = await FCM.requestPermissions({badge: false, sound: true, alert: true});
    } catch(e){
      console.error(e);
    }

    FCM.getFCMToken().then(token => {
      console.log("TOKEN (getFCMToken)", token);
      this.setState({token: token || ""})
    });

    if(Platform.OS === 'ios'){
      FCM.getAPNSToken().then(token => {
        console.log("APNS TOKEN (getFCMToken)", token);
      });
    }
Libin Lu's avatar
Libin Lu committed
66 67 68 69
	  
	  // topic example
	  // FCM.subscribeToTopic('sometopic')
	  // FCM.unsubscribeFromTopic('sometopic')
Libin Lu's avatar
Libin Lu committed
70 71
  }

Libin Lu's avatar
Libin Lu committed
72 73
  showLocalNotification() {
    FCM.presentLocalNotification({
Libin Lu's avatar
Libin Lu committed
74
      id: new Date().valueOf().toString(),                // (optional for instant notification)
Libin Lu's avatar
Libin Lu committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
      title: "Test Notification with action",             // as FCM payload
      body: "Force touch to reply",                       // as FCM payload (required)
      sound: "bell.mp3",                                  // "default" or filename
      priority: "high",                                   // as FCM payload
      click_action: "com.myapp.MyCategory",               // as FCM payload - this is used as category identifier on iOS.
      badge: 10,                                          // as FCM payload IOS only, set 0 to clear badges
      number: 10,                                         // Android only
      ticker: "My Notification Ticker",                   // Android only
      auto_cancel: true,                                  // Android only (default true)
      large_icon: "https://image.freepik.com/free-icon/small-boy-cartoon_318-38077.jpg",                           // Android only
      icon: "ic_launcher",                                // as FCM payload, you can relace this with custom icon you put in mipmap
      big_text: "Show when notification is expanded",     // Android only
      sub_text: "This is a subText",                      // Android only
      color: "red",                                       // Android only
      vibrate: 300,                                       // Android only default: 300, no vibration if you pass 0
      wake_screen: true,                                  // Android only, wake up screen when notification arrives
      group: "group",                                     // Android only
      picture: "https://google.png",                      // Android only bigPicture style
      ongoing: true,                                      // Android only
      my_custom_data:'my_custom_field_value',             // extra data you want to throw
      lights: true,                                       // Android only, LED blinking (default false)
      show_in_foreground: true                           // notification when app is in foreground (local & remote)
Libin Lu's avatar
Libin Lu committed
97 98 99
    });
  }

Libin Lu's avatar
Libin Lu committed
100 101 102 103 104 105 106
  scheduleLocalNotification() {
    FCM.scheduleLocalNotification({
      id: 'testnotif',
      fire_date: new Date().getTime()+5000,
      vibrate: 500,
      title: 'Hello',
      body: 'Test Scheduled Notification',
Libin Lu's avatar
Libin Lu committed
107
      sub_text: 'sub text',
Libin Lu's avatar
Libin Lu committed
108
      priority: "high",
Libin Lu's avatar
Libin Lu committed
109
      large_icon: "https://image.freepik.com/free-icon/small-boy-cartoon_318-38077.jpg",
Libin Lu's avatar
Libin Lu committed
110
      show_in_foreground: true,
Libin Lu's avatar
Libin Lu committed
111
      picture: 'https://firebase.google.com/_static/af7ae4b3fc/images/firebase/lockup.png',
Libin Lu's avatar
Libin Lu committed
112 113 114
      wake_screen: true,
      extra1: {a: 1},
      extra2: 1
Libin Lu's avatar
Libin Lu committed
115 116 117
    });
  }

Libin Lu's avatar
Libin Lu committed
118 119 120 121 122 123 124 125 126
  sendRemoteNotification(token) {
    let body;

    if(Platform.OS === 'android'){
      body = {
        "to": token,
      	"data":{
					"custom_notification": {
						"title": "Simple FCM Client",
Libin Lu's avatar
Libin Lu committed
127
						"body": "Click me to go to detail",
Libin Lu's avatar
Libin Lu committed
128 129
						"sound": "default",
						"priority": "high",
Libin Lu's avatar
Libin Lu committed
130 131
            "show_in_foreground": true,
            targetScreen: 'detail'
Libin Lu's avatar
Libin Lu committed
132 133 134 135 136 137 138 139 140
        	}
    		},
    		"priority": 10
      }
    } else {
			body = {
				"to": token,
				"notification":{
					"title": "Simple FCM Client",
Libin Lu's avatar
Libin Lu committed
141
					"body": "Click me to go to detail",
Libin Lu's avatar
Libin Lu committed
142
					"sound": "default"
Libin Lu's avatar
Libin Lu committed
143 144 145 146
        },
        data: {
          targetScreen: 'detail'
        },
Libin Lu's avatar
Libin Lu committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
				"priority": 10
			}
		}

    firebaseClient.send(JSON.stringify(body), "notification");
  }

  sendRemoteData(token) {
    let body = {
    	"to": token,
      "data":{
    		"title": "Simple FCM Client",
    		"body": "This is a notification with only DATA.",
    		"sound": "default"
    	},
    	"priority": "normal"
    }

    firebaseClient.send(JSON.stringify(body), "data");
  }

Libin Lu's avatar
Libin Lu committed
168 169 170 171 172 173
  showLocalNotificationWithAction() {
    FCM.presentLocalNotification({
      title: 'Test Notification with action',
      body: 'Force touch to reply',
      priority: "high",
      show_in_foreground: true,
Libin Lu's avatar
Libin Lu committed
174 175 176 177 178 179 180 181
      click_action: "com.myidentifi.fcm.text", // for ios
      android_actions: JSON.stringify([{
        id: "view",
        title: 'view'
      },{
        id: "dismiss",
        title: 'dismiss'
      }]) // for android, take syntax similar to ios's. only buttons are supported
Libin Lu's avatar
Libin Lu committed
182
    });
Libin Lu's avatar
Libin Lu committed
183 184
  }

renato's avatar
renato committed
185
  render() {
186
    let { token, tokenCopyFeedback } = this.state;
187

renato's avatar
renato committed
188 189
    return (
      <View style={styles.container}>
Libin Lu's avatar
Libin Lu committed
190
      <ScrollView style={{paddingHorizontal: 20}}>
renato's avatar
renato committed
191 192 193 194
        <Text style={styles.welcome}>
          Welcome to Simple Fcm Client!
        </Text>

195 196 197 198
        <Text style={styles.feedback}>
          {this.state.tokenCopyFeedback}
        </Text>

Libin Lu's avatar
Libin Lu committed
199 200 201 202
        <Text style={styles.feedback}>
          Remote notif won't be available to iOS emulators
        </Text>

Libin Lu's avatar
Libin Lu committed
203
        <TouchableOpacity onPress={() => this.sendRemoteNotification(token)} style={styles.button}>
Libin Lu's avatar
Libin Lu committed
204
          <Text style={styles.buttonText}>Send Remote Notification</Text>
renato's avatar
renato committed
205 206
        </TouchableOpacity>

Libin Lu's avatar
Libin Lu committed
207
        <TouchableOpacity onPress={() => this.sendRemoteData(token)} style={styles.button}>
Libin Lu's avatar
Libin Lu committed
208
          <Text style={styles.buttonText}>Send Remote Data</Text>
renato's avatar
renato committed
209
        </TouchableOpacity>
renato's avatar
renato committed
210

Libin Lu's avatar
Libin Lu committed
211 212
        <TouchableOpacity onPress={() => this.showLocalNotification()} style={styles.button}>
          <Text style={styles.buttonText}>Show Local Notification</Text>
renato's avatar
renato committed
213
        </TouchableOpacity>
Libin Lu's avatar
Libin Lu committed
214

Libin Lu's avatar
Libin Lu committed
215
        <TouchableOpacity onPress={() => this.showLocalNotificationWithAction(token)} style={styles.button}>
Libin Lu's avatar
Libin Lu committed
216
          <Text style={styles.buttonText}>Show Local Notification with Action</Text>
Libin Lu's avatar
Libin Lu committed
217
        </TouchableOpacity>
Libin Lu's avatar
Libin Lu committed
218 219 220 221

        <TouchableOpacity onPress={() => this.scheduleLocalNotification()} style={styles.button}>
          <Text style={styles.buttonText}>Schedule Notification in 5s</Text>
        </TouchableOpacity>
Libin Lu's avatar
Libin Lu committed
222

Libin Lu's avatar
Libin Lu committed
223 224 225
        <Text style={styles.instructions}>
          Init notif:
        </Text>
Libin Lu's avatar
Libin Lu committed
226
        <Text>
Libin Lu's avatar
Libin Lu committed
227
          {JSON.stringify(this.state.initNotif)}
Libin Lu's avatar
Libin Lu committed
228 229
        </Text>

Libin Lu's avatar
Libin Lu committed
230 231
        <Text style={styles.instructions}>
          Token:
Libin Lu's avatar
Libin Lu committed
232
        </Text>
Libin Lu's avatar
Libin Lu committed
233 234 235 236
        <Text selectable={true} onPress={() => this.setClipboardContent(this.state.token)}>
          {this.state.token}
        </Text>
        </ScrollView>
renato's avatar
renato committed
237 238 239
      </View>
    );
  }
240 241 242 243 244 245 246 247 248 249

  setClipboardContent(text) {
    Clipboard.setString(text);
    this.setState({tokenCopyFeedback: "Token copied to clipboard."});
    setTimeout(() => {this.clearTokenCopyFeedback()}, 2000);
  }

  clearTokenCopyFeedback() {
    this.setState({tokenCopyFeedback: ""});
  }
renato's avatar
renato committed
250 251
}

Libin Lu's avatar
Libin Lu committed
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
class DetailPage extends Component {
  render(){
    return <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Detail page</Text>
    </View>
  }
}

export default StackNavigator({
  Main: {
    screen: MainPage,
  },
  Detail: {
    screen: DetailPage
  }
}, {
  initialRouteName: 'Main',
});

renato's avatar
renato committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
286 287 288 289 290 291
    marginBottom: 2,
  },
  feedback: {
    textAlign: 'center',
    color: '#996633',
    marginBottom: 3,
renato's avatar
renato committed
292 293 294 295
  },
  button: {
    backgroundColor: "teal",
    paddingHorizontal: 20,
Libin Lu's avatar
Libin Lu committed
296 297
    paddingVertical: 15,
    marginVertical: 10,
renato's avatar
renato committed
298 299 300 301 302 303 304
    borderRadius: 10
  },
  buttonText: {
    color: "white",
    backgroundColor: "transparent"
  },
});