Last active
June 27, 2019 16:09
-
-
Save hikiit/2f31f537064155daa37c23e9e5238066 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class _CounterPageState extends State<CounterPage> { | |
final _random = Random(); | |
final _db = Firestore.instance; | |
// Shardsをすべて削除し、counter1に記載されたShards数で初期化 | |
void _initFirestore() async { | |
// Shardsサブコレクションがすでに存在しているかチェック | |
QuerySnapshot shardsSnapshot = await _db | |
.collection('counters') | |
.document('counter1') | |
.collection('shards') | |
.getDocuments(); | |
if (shardsSnapshot.documents[0].exists) { | |
// クライアントからのdelete()は非推奨 | |
for (DocumentSnapshot document in shardsSnapshot.documents) { | |
document.reference.delete(); | |
} | |
} | |
// 作成するShards数を取得 | |
var numShardsSnapshot = | |
await _db.collection('counters').document('counter1').get(); | |
var numShards = numShardsSnapshot['num_shards']; | |
// batchで一括初期化 | |
var batch = _db.batch(); | |
final counter1 = _db.collection('counters').document('counter1'); | |
for (int i = 0; i < numShards; i++) { | |
batch.setData( | |
counter1.collection('shards').document(i.toString()), {'count': 0}); | |
} | |
batch.commit(); | |
} | |
// 分散カウンタ | |
// counter1のサブコレクションであるShardをランダムに1つ選択し、カウントアップ | |
void _incrementShard() async { | |
// Shardsの数を取得する | |
var numShardsSnapshot = | |
await _db.collection('counters').document('counter1').get(); | |
var numShards = numShardsSnapshot['num_shards']; | |
// トランザクションでカウントアップ | |
_db.runTransaction((Transaction tx) async { | |
final sharedId = _random.nextInt(numShards); | |
final DocumentReference postRef = | |
_db.document('/counters/counter1/shards/' + sharedId.toString()); | |
DocumentSnapshot postSnapshot = await tx.get(postRef); | |
if (postSnapshot.exists) { | |
await tx.update( | |
postRef, <String, int>{'count': postSnapshot.data['count'] + 1}); | |
} | |
}); | |
} | |
// Shardsサブコレクションに変更があったらShardsサブコレクションを合計値を再計算 | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(widget.title), | |
), | |
body: Column( | |
children: <Widget>[ | |
Padding( | |
padding: const EdgeInsets.all(20.0), | |
child: StreamBuilder<QuerySnapshot>( | |
stream: _db | |
.collection('counters') | |
.document('counter1') | |
.collection('shards') | |
.snapshots(), | |
builder: (BuildContext context, | |
AsyncSnapshot<QuerySnapshot> snapshot) { | |
if (snapshot.hasError) | |
return new Text('Error: ${snapshot.error}'); | |
switch (snapshot.connectionState) { | |
case ConnectionState.waiting: | |
return new Text('Loading...'); | |
default: | |
var count = 0; | |
for (DocumentSnapshot document in snapshot.data.documents) { | |
count += document['count']; | |
} | |
return Center(child: new Text(count.toString())); | |
} | |
}, | |
), | |
), | |
Padding( | |
padding: const EdgeInsets.all(20.0), | |
child: RaisedButton( | |
child: Text('初期化'), | |
color: Colors.lightBlue, | |
onPressed: () { | |
_initFirestore(); | |
}, | |
), | |
), | |
], | |
), | |
floatingActionButton: FloatingActionButton( | |
// 1タップで100回インクリメントする | |
onPressed: () { | |
for (int i = 0; i < 100; i++) { | |
_incrementShard(); | |
} | |
}, | |
child: Icon(Icons.thumb_up), | |
backgroundColor: Colors.pink, | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment