2020年8月3日月曜日

文字列処理 time.afterの怪 構造体の外だしの怪

文字列(string型) 文字列は "" ダブルクオートで囲む

package main

 

func main() {

    s := "hello world"

    println(s) // hello world

}

エスケープシーケンス

\"  ダブルクオート

\n  改行(line feed)

\r  復帰(carriage return)

\t  水平タブ

\v  垂直タブ

文字列は "" で囲むので " を文字列に含めることはできません。

なので \ (バックスラッシュ) に続けて " を記述することでそれを使うことができます。

その他にも \n で改行、 \t で水平タブなどを表現します。

package main

func main() {

    var s string

    // "" を出力する

    s = "\"hello\""

    println(s)

    // "hello"

    // 改行

    s = "hello\nworld"

    println(s)

    // hello

    // world

    // 水平タブ

    s = "\thello"

    println(s)

    //         hello

}

 

 

 

文字数の取得

package main

func main() {

    s := "hello world"

    length := len(s)

    println(length) // 11 }

文字列から一文字取得 文字列(string型)は、バイトスライス([]byte)としてスライスと同様にインデックス番号(添え字)で文字(byte)が取得できる

package main

func main() {

    s := "hello world"

    b := s[0]

    println(string(b)) // h }

文字列の切り取り これもスライスと同じで [start:end] で抜き出すことができる。

package main

func main() {

    s := "hello world"

    b := s[0:5]

    println(string(b)) // hello }

連結演算子(文字列の連結) + を使って文字列を連結できる

package main

func main() {

    a := "Hello" + "World"

    println(a) // HelloWorld

    // 変数でも同じ

    b := "Hello"

    c := "World"

    d := b + c

    println(d) // HelloWorld

    // 片方が変数でも同じ

    e := "Hello"

    f := e + "World"

    println(f) // HelloWorld

    g := "Hello"  // += で g = g + "World" と同じ意味になる

    g += "World"

    println(g) // HelloWorld }

ヒアドキュメント "" の代わりに `` (バッククォート)で囲むことで、そのまま複数行の文字列を書くことができます。 エスケープシーケンスはそのまま表示されるので、以下のように \n\r\t\v がそのまま出力されます。

package main

func main() {

    s := `foo\n\r\t\v

  bar

baz`

 

    println(s)

    // foo\n\r\t\v

    //         bar

    // baz

}

 

シングルバイト文字(byte)とマルチバイト文字(rune)

byte (uint8 の別名)。8ビット = 1バイト ジングルバイト文字

e-words: シングルバイト文字

rune (int32 の別名)。1バイト以上なのでマルチバイト文字(日本語など)

e-words: マルチバイト文字

package main

import "fmt"

func main() {

    s := "こんにちは"

    // 5文字なのに 15 になる

    fmt.Println(len(s))       // 15

    // マルチバイト文字は正しく出力されない

    fmt.Println(string(s[0])) // ã

    // []byteにすると1バイトごとにスライスになる。

    // 1バイトごとのスライスを数えるので上の len(s) は 15 になるし、

    //  s[0] での抜き出しも正しく出力されない

    fmt.Println([]byte(s))

    // [227 129 147 227 130 147 227 129 171 227 129 161 227 129 175]

    // []runeにすると文字ごとにスライスになる

    fmt.Println([]rune(s))

    // [12371 12435 12395 12385 12399] }

マルチバイトの文字数取得 unicode/utf8パッケージ

package main

import "unicode/utf8"

func main() {

    s := "こんにちは"

    // []rune にしてから長さを数える

    r := []rune(s)

    println(len(r)) // 5

    // runeの長さを数える関数を使う

    println(utf8.RuneCountInString(s)) // 5

}

 

マルチバイトの文字を取得 一度 []rune に変換する

package main

func main() {

    s := "hello こんにちは"

    r := []rune(s)

    println(string(r[6]))  // こ

    println(string(r[7]))  // ん

    println(string(r[8]))  // に

    println(string(r[9]))  // ち

    println(string(r[10])) // は

}

マルチバイト文字の切り取り

package main

import "strings"

func main() {

    s := "hello こんにちは"

    // 一度 []rune にして抜き出す

    r := []rune(s)

    println(string(r[6:len(s)])) // こんにちは

    // strings パッケージの Index 関数を使えば開始位置がわかる

    target := "こんにちは"

    if i := strings.Index(s, target); i != -1 {

        println(s[i : i+len(target)]) // こんにちは

    } }

文字列のループ for 文は、[]byte をインデックス番号で取得するので byte/uint8 になる。なので、これもマルチバイト文字は正確に扱うことができない。

 

package main

import (

    "reflect"

)

func main() {

    s := "hello"

    for i := 0; i < len(s); i++ {

        kind := reflect.TypeOf(s[i]).String()

        println(kind) // uint8

    }

}

 

対して、for...range のは、変数に rune/int32 がセットされる。 []rune としてループする

 

package main

import (

    "reflect"

)

func main() {

    s := "hello"

    for _, v := range s {

        kind := reflect.TypeOf(v).String()

        println(kind) // int32

    }

}

 

 

 

 

 

 

 

シングルバイト文字とマルチバイト文字の判別

package main

import (

    "fmt"

    "unicode/utf8"

)

 

func main() {

    s := "hello こんにちは 12345"

 

    for _, v := range s {

        if v < utf8.RuneSelf {

            fmt.Println("Singlebyte char:", string(v))

        } else {

            fmt.Println("Multibyte char :", string(v))

        }

    }

}

 

 

 

文字列に関する便利な標準パッケージ

stringsパッケージ

https://golang.org/pkg/strings/

 

fmtパッケージ

https://golang.org/pkg/fmt/

 

strconvパッケージ

https://golang.org/pkg/strconv/

 

textパッケージ

https://golang.org/pkg/text/

 

--------------------------------------------------
package main

import (
"bufio"
"fmt"
"log"
"net"
"time"
)

type client struct {
who string
ch  chan<- string // an outgoing message channel
}

const limitTimeout = 30 * time.Second

// const limitTimeout = 10 * time.Second

var (
entering = make(chan client)
leaving  = make(chan client)
messages = make(chan string) // all incoming client messages
)

func broadcaster() {
clients := make(map[client]bool) // all connected clients
for {
select {
case msg := <-messages:
// Broadcast incoming message to all
// clients' outgoing message channels.
for cli := range clients {
cli.ch <- msg
}

case cli := <-entering:
if len(clients) > 0 {
cli.ch <- "active users: "
for other := range clients {
cli.ch <- "\t" + other.who
}
}
clients[cli] = true

case cli := <-leaving:
delete(clients, cli)
close(cli.ch)
}
}
}

func handleConn(conn net.Conn) {
ch := make(chan string) // outgoing client messages
go clientWriter(conn, ch)

who := conn.RemoteAddr().String()
ch <- "You are " + who
messages <- who + " has arrived"
entering <- client{who, ch}

timer := time.AfterFunc(limitTimeout, func() {
conn.Close()

})
  // ここで終わるのでleaving,messagesは実施されないと思いきや
        //  conn.Close()にたどり着く前の操作を終えてくれる!
input := bufio.NewScanner(conn)
for input.Scan() {
messages <- who + ": " + input.Text()
timer.Reset(limitTimeout)
}
// NOTE: ignoring potential errors from input.Err()

leaving <- client{who, ch}
messages <- who + " has left"

conn.Close()
}

func clientWriter(conn net.Conn, ch <-chan string) {
for msg := range ch {
fmt.Fprintln(conn, msg) // NOTE: ignoring network errors
}
}

func main() {
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}

go broadcaster()
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
continue
}
go handleConn(conn)
}
}

------------------------------------------------------
Goの構造体をpackageに外出ししてハマッたこと

2020年7月14日火曜日

thumbnail using goroutine stream

// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/

// +build ignore

// The thumbnail command produces thumbnails of JPEG files
// whose names are provided on each line of the standard input.
//
// The "+build ignore" tag (see p.295) excludes this file from the
// thumbnail package, but it can be compiled as a command and run like
// this:
//
// Run with:
//   $ go run $GOPATH/src/gopl.io/ch8/thumbnail/main.go
//   foo.jpeg
//   ^D
//
package main

import (
"bufio"
"fmt"
"log"
"os"

"gopl.io/ch8/thumbnail"
)

func main() {
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
thumb, err := thumbnail.ImageFile(input.Text())
if err != nil {
log.Print(err)
continue
}
fmt.Println(thumb)
}
if err := input.Err(); err != nil {
log.Fatal(err)
}
}
// thumnail.go
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/

// See page 234.

// The thumbnail package produces thumbnail-size images from
// larger images.  Only JPEG images are currently supported.
package thumbnail

import (
"fmt"
"image"
"image/jpeg"
"io"
"os"
"path/filepath"
"strings"
)

// Image returns a thumbnail-size version of src.
func Image(src image.Image) image.Image {
// Compute thumbnail size, preserving aspect ratio.
xs := src.Bounds().Size().X
ys := src.Bounds().Size().Y
width, height := 128, 128
if aspect := float64(xs) / float64(ys); aspect < 1.0 {
width = int(128 * aspect) // portrait
} else {
height = int(128 / aspect) // landscape
}
xscale := float64(xs) / float64(width)
yscale := float64(ys) / float64(height)

dst := image.NewRGBA(image.Rect(0, 0, width, height))

// a very crude scaling algorithm
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
srcx := int(float64(x) * xscale)
srcy := int(float64(y) * yscale)
dst.Set(x, y, src.At(srcx, srcy))
}
}
return dst
}

// ImageStream reads an image from r and
// writes a thumbnail-size version of it to w.
func ImageStream(w io.Writer, r io.Reader) error {
src, _, err := image.Decode(r)
if err != nil {
return err
}
dst := Image(src)
return jpeg.Encode(w, dst, nil)
}

// ImageFile2 reads an image from infile and writes
// a thumbnail-size version of it to outfile.
func ImageFile2(outfile, infile string) (err error) {
in, err := os.Open(infile)
if err != nil {
return err
}
defer in.Close()

out, err := os.Create(outfile)
if err != nil {
return err
}

if err := ImageStream(out, in); err != nil {
out.Close()
return fmt.Errorf("scaling %s to %s: %s", infile, outfile, err)
}
return out.Close()
}

// ImageFile reads an image from infile and writes
// a thumbnail-size version of it in the same directory.
// It returns the generated file name, e.g. "foo.thumb.jpeg".
func ImageFile(infile string) (string, error) {
ext := filepath.Ext(infile) // e.g., ".jpg", ".JPEG"
outfile := strings.TrimSuffix(infile, ext) + ".thumb" + ext
return outfile, ImageFile2(outfile, infile)
}

// thum_test_test.go

// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/

// This file is just a place to put example code from the book.
// It does not actually run any code in gopl.io/ch8/thumbnail.

package thumbnail_test

import (
"log"
"os"
"sync"

"gopl.io/ch8/thumbnail"
)

//!+1
// makeThumbnails makes thumbnails of the specified files.
func makeThumbnails(filenames []string) {
for _, f := range filenames {
if _, err := thumbnail.ImageFile(f); err != nil {
log.Println(err)
}
}
}

//!-1

//!+2
// NOTE: incorrect!
func makeThumbnails2(filenames []string) {
for _, f := range filenames {
go thumbnail.ImageFile(f) // NOTE: ignoring errors
}
}

//!-2

//!+3
// makeThumbnails3 makes thumbnails of the specified files in parallel.
func makeThumbnails3(filenames []string) {
ch := make(chan struct{})
for _, f := range filenames {
go func(f string) {
thumbnail.ImageFile(f) // NOTE: ignoring errors
ch <- struct{}{}
}(f)
}

// Wait for goroutines to complete.
for range filenames {
<-ch
}
}

//!-3

//!+4
// makeThumbnails4 makes thumbnails for the specified files in parallel.
// It returns an error if any step failed.
func makeThumbnails4(filenames []string) error {
errors := make(chan error)

for _, f := range filenames {
go func(f string) {
_, err := thumbnail.ImageFile(f)
errors <- err
}(f)
}

for range filenames {
if err := <-errors; err != nil {
return err // NOTE: incorrect: goroutine leak!
}
}

return nil
}

//!-4

//!+5
// makeThumbnails5 makes thumbnails for the specified files in parallel.
// It returns the generated file names in an arbitrary order,
// or an error if any step failed.
func makeThumbnails5(filenames []string) (thumbfiles []string, err error) {
type item struct {
thumbfile string
err       error
}

ch := make(chan item, len(filenames))
for _, f := range filenames {
go func(f string) {
var it item
it.thumbfile, it.err = thumbnail.ImageFile(f)
ch <- it
}(f)
}

for range filenames {
it := <-ch
if it.err != nil {
return nil, it.err
}
thumbfiles = append(thumbfiles, it.thumbfile)
}

return thumbfiles, nil
}

//!-5

//!+6
// makeThumbnails6 makes thumbnails for each file received from the channel.
// It returns the number of bytes occupied by the files it creates.
func makeThumbnails6(filenames <-chan string) int64 {
sizes := make(chan int64)
var wg sync.WaitGroup // number of working goroutines
for f := range filenames {
wg.Add(1)
// worker
go func(f string) {
defer wg.Done()
thumb, err := thumbnail.ImageFile(f)
if err != nil {
log.Println(err)
return
}
info, _ := os.Stat(thumb) // OK to ignore error
sizes <- info.Size()
}(f)
}

// closer
go func() {
wg.Wait()
close(sizes)
}()

var total int64
for size := range sizes {
total += size
}
return total
}

//!-6
package main

import (
//"bufio"
//"fmt"
"log"
"os"
"sync"

"gopl.io/ch8/thumbnail"
)

func makeThumbnails6(filenames <-chan string) int64 {
sizes := make(chan int64)
var wg sync.WaitGroup // number of working goroutines
for f := range filenames {
wg.Add(1)
// worker
go func(f string) {
defer wg.Done()
thumb, err := thumbnail.ImageFile(f)
if err != nil {
log.Println(err)
return
}
info, _ := os.Stat(thumb) // OK to ignore error
sizes <- info.Size()
}(f)
}

// closer
go func() {
wg.Wait()
close(sizes)
}()

var total int64
for size := range sizes {
total += size
}
return total
}
----------------------------------------------------------------------  using stream
func main() {
files := []string{"monkey.jpeg","elephant.jpeg"}
generator := func(files []string) <-chan string {
fileStream := make(chan string)
go func() {
defer close(fileStream)
for _, f := range files {
fileStream <- f
}
}()
return fileStream
}
filenames := generator(files)

makeThumbnails6(filenames)
}
---------------------------------------------------------------------------- another using stream
package main

import (
//"bufio"
//"fmt"
//"log"
//"os"

"gopl.io/ch8/thumbnail"
)
func makeThumbnails5(filenames []string) (thumbfiles []string, err error) {
type item struct {
thumbfile string
err       error
}

ch := make(chan item, len(filenames))
for _, f := range filenames {
go func(f string) {
var it item
it.thumbfile, it.err = thumbnail.ImageFile(f)
ch <- it
}(f)
}

for range filenames {
it := <-ch
if it.err != nil {
return nil, it.err
}
thumbfiles = append(thumbfiles, it.thumbfile)
}

return thumbfiles, nil
}
func main() {
files := []string{"monkey.jpeg","elephant.jpeg"}
makeThumbnails5(files)
}

2020年7月5日日曜日

crawl3a and tee.go

 // Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/

// See page 243.

// Crawl3 crawls web links starting with the command-line arguments.
//
// This version uses bounded parallelism.
// For simplicity, it does not address the termination problem.
//
package main

import (
"fmt"
"log"
"os"

"./links"
)

func crawl(url string) []string {
fmt.Println(url)
list, err := links.Extract(url)
if err != nil {
log.Print(err)
}
return list
}

//!+
func main() {
worklist := make(chan []string)  // lists of URLs, may have duplicates
unseenLinks := make(chan string) // de-duplicated URLs
    var n int
// Add command-line arguments to worklist.
go func() { worklist <- os.Args[1:] }()

// Create 20 crawler goroutines to fetch each unseen link.
for i := 0; i < 20; i++ {
go func() {
for link := range unseenLinks {
foundLinks := crawl(link)
go func() { worklist <- foundLinks }()
}
}()
}

// The main goroutine de-duplicates worklist items
// and sends the unseen ones to the crawlers.
seen := make(map[string]bool)
n++
for ; n > 0; n-- {
    list := <-worklist
for _, link := range list {
if !seen[link] {
seen[link] = true
n++
unseenLinks <- link
}
}
}
}

//!-
---------------------

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
package main

import (
    "fmt"
)

func main() {

        repeat := func(
        done <-chan interface{},
        values ...interface{},
    ) <-chan interface{} {
        valueStream := make(chan interface{})
        go func() {
            defer close(valueStream)
            for {
                for _, v := range values {
                    select {
                    case <-done:
                        return
                    case valueStream <- v:
                    }
                }
            }
        }()
        return valueStream
    }
   
    take := func(
        done <-chan interface{},
        valueStream <-chan interface{},
        num int,
    ) <-chan interface{} {
        takeStream := make(chan interface{})
        go func() {
            defer close(takeStream)
            for i := 0; i < num; i++ {
                select {
                case <-done:
                    return
                case takeStream <- <-valueStream:
                }
            }
        }()
        return takeStream
    }
   
    orDone := func(done, c <-chan interface{}) <-chan interface{} {
        valStream := make(chan interface{})
        go func() {
            defer close(valStream)
            for {
                select {
                case <-done:
                    return
                case v, ok := <-c:
                    if ok == false {
                        return
                    }
                    select {
                    case valStream <- v:
                    case <-done:
                    }
                }
            }
        }()
        return valStream
    }
   
    tee := func(
      done <- chan interface{},
      in <- chan interface{},
      ) (_, _ <- chan interface{}) {
       out1 := make(chan interface{})
       out2 := make(chan interface{})
       go func() {
         defer close(out1)
         defer close(out2)
         for val := range orDone(done, in) {
          var out1, out2 = out1, out2
          for i := 0; i < 2; i++ {
            select {
              case out1<-val:
                out1 = nil
              case out2<-val:
                out2 = nil
            }
          }
       }
      }()
      return out1, out2
    }
   
    done := make(chan interface{})
    defer close(done)
   
    out1, out2 := tee(done, take(done, repeat(done, 1, 2), 4))
   
    for val1 := range out1 {
      fmt.Printf("out1: %v, out2: %v\n", val1, <-out2)
    }
   
}

2020年6月20日土曜日

actix web-json-api

Rust :: rustbook and rust-by-example is good site

https://qiita.com/yukinarit/items/c5128e67d168b4f39983 中途半端なrocket api

https://rohki.hatenablog.com/entry/2018/08/03/200805 :: cargo run --example is for examples folder's codes....

https://qiita.com/kenmaro/items/652204a7afd7c870b7db
:: ソースコードのmain.rsでweb_dieselのところをcrateにしたらできた

diesel_cli instasll some lib ::
 PostgreSQL は libpq-dev , MySQL は libmysqlclient-dev, SQLite は libsqlite3-dev

https://medium.com/@fdeantoni/rust-actix-diesel-sqlite-d67a1c3ef0e
::actix diesel sqlite executable sample ただしmain.rsにHttpRequestを付加せんと動かん
curl http://127.0.0.1:8088/create -H "Content-Type: application/json" -d '{"title": "socks", "body": "summary"}'  :: ok

http://gouf.hatenablog.com/entry/2019/04/16/200240 :: sqlite on memory OK

https://keens.github.io/blog/2018/12/08/rustnomoju_runotsukaikata_2018_editionhan/ :: mod system in rust
--------------------------------------------------------------------------------------------

 http://paperface.hatenablog.com/entry/2019/02/08/%E3%80%90Ubuntu_%2B_PostgreSQL%E3%80%91Ubuntu_18_04%E3%81%ABPostgreSQL_11_1%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB :: pg install and hba-changed
or  http://db-study.com/archives/121 and https://cpoint-lab.co.jp/article/201807/4217/
:: also useful

https://stackoverflow.com/questions/39281594/error-1698-28000-access-denied-for-user-rootlocalhost :: mysql install and auth-socket delete

---------------------------------------------------------------------------------------------------
 http://linuxc.info/process/process2.html :: #include <sys/wait.h> needed!

2020年6月13日土曜日

wifi and ppa update // diesel actix-web rocket

 https://qiita.com/chikoski/items/b6461367e8c3875bb235 :: nightyl install
https://qiita.com/yukinarit/items/c5128e67d168b4f39983 :: webapi  tutor
https://qiita.com/kenmaro/items/07735625858e9333fc83#serde%E3%81%AEcrate%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B::base
----------------------------------------------------------------------------------------
https://mshr-t.hatenablog.jp/entry/2019/06/10/032205 mysqlでうまくDieselでき
diesel cli は別にインスト要した mysql,postgres,sqliteそれぞれライブラリのインストが必要

https://qiita.com/atsuk/items/c04fffe4ed0e73a67cd0 :: actix-web manual...

 https://dev.classmethod.jp/articles/actix-web/ ::actix-web
ll https://qiita.com/yukinarit/items/c5128e67d168b4f39983 :: rocket-webapi

----------------------------------------------------------------------------------------------

 https://blog.techlab-xe.net/linux-use-usb-wifi-2016/ ::wifi install memo

https://qiita.com/nyanchu/items/a8cfc5cf627d70d798bf :: ubuntu apt update memo

2020年5月16日土曜日

Nuxt.js + Firebase Authentication + FireStoreでwebアプリケーションハンズオン

https://qiita.com/ririli/items/d0d3a6ae78c1b6e827fc

index.js::

import firebase from '~/plugins/firebase'
const db = firebase.firestore();

const todoRef = db.collection('todos')

export const state = () => ({
 userUid: '',
 userName: '',
 todos: []
})

export const mutations = {
 setUserUid(state,userUid) {
   state.userUid = userUid
 },
 setUserName(state,userName) {
   state.userName = userName
 },
 addTodo(state, todo) {
   state.todos.push(todo)
 },
 clearTodo(state) {
  state.todo = []
 }
}

export const actions = {
 login({ commit }) {
    console.log('login action')
    const provider = new firebase.auth.GoogleAuthProvider();
    firebase.auth().signInWithPopup(provider).then(function(result) {
      const user = result.user;

     console.log('success : ' + user.uid + ' : ' + user.displayName)
     commit('setUserUid', user.uid)
     commit('setUserName', user.displayName)
    }).catch(function(error) {
      var errorCode = error.code;
      console.log('error : ' + errorCode)
    });
  },
   fetchTodos({ commit }) {
  todoRef
  .get()
   .then(res => {
     res.forEach((doc) => {
       console.log('success : ' + `${doc.id} => ${doc.data()}`);
       commit('addTodo', doc.data())
     })
   })
   .catch(error => {
     console.log('error : ' + error)
   })
 },
  addTodo({commit}, todo) {
   console.log(todo)
   todoRef
   .add({
     todo: todo.todo,
     limit: todo.limit,
   })
   .then(function(docRef) {
     console.log("Document written with ID: ", docRef.id);
     commit('addTodo', todo)
   })
   .catch(function(error) {
     console.error("Error adding document: ", error);
   });
 }
}

export const getters = {
 getUserUid(state) {
   return state.userUid
 },
 getUserName(state) {
   return state.userName
   },
  getTodos(state) {
   return state.todos
 }
}

index.vue::

<template>
  <div class="container">
      <p class="title is-1 is-spaced">user: {{ $store.getters.getUserName }}</p>
      <button class="button is-primary is-rounded" @click="login">
        ログイン
      </button>

    <table class="table is-narrow">
      <tbody>
         <tr>
           <th>todo</th>
           <th>limit</th>
         </tr>
       </tbody>
       <tbody>
         <tr v-for="todo in $store.getters.getTodos" :key="todo">
           <td>{{todo.todo}}</td>
          <td>{{todo.limit}}</td>
         </tr>
       </tbody>
     </table>
    <div class="field is-grouped">
     <p class="control is-expanded">
       <input v-model="newTodo" class="input" type="text" placeholder="todo">
     </p>
     <p class="control is-expanded">
       <input v-model="newLimit" class="input" type="text" placeholder="limit">
     </p>
     <p class="control">
       <a class="button is-primary" @click="addTodo">
         add
       </a>
     </p>
   </div>
  </div>
</template>
<script>
export default {
   data() {
  return {
    newTodo: '',
    newLimit: ''
   }
 },
  methods: {
    login() {
     console.log('login')
this.$store.dispatch('login')
} ,
   addTodo() {
     const todo = this.newTodo
    const limit = this.newLimit
 
     this.$store.dispatch('addTodo', {todo, limit})
     this.newTodo = ''
     this.newLimit = ''
    }
   ,
   created() {
    this.$store.dispatch('fetchTodos')
   }
  }
 }
</script>
<style>
.container {
  margin: 0 auto;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
</style>
firebase.js::
import firebase from 'firebase'

if (!firebase.apps.length) {
  firebase.initializeApp(
    {
  snippets for axios-ex
    }
  )
}


export default firebase
---------------------------------------------------------------
https://note.com/aokha/n/ne3a3f604a1c0 
Firebase+Nuxt.jsでGoogle認証機能を実装してみた なんか中途半端なコード

2020年5月13日水曜日

vue and nuxt and firebase

【Nuxt.js】firebase導入編(RDB版):データの追加 取得をしようhttps://note.com/aliz/n/nc61318a7c431 にあるpluginで①を付け加える必要あった

import firebase from "firebase/app"
import 'firebase/database' // ①
//もしくは上の二行のかわりに
// import firebase from "firebase" でもいいが。。。。
if (!firebase.apps.length) {
 firebase.initializeApp({
   apiKey: "AIzaSyDR25V6IjIMmOGRky-Gu7IFk-xk6hfzl-I",
    authDomain: "axios-ex.firebaseapp.com",
    databaseURL: "https://axios-ex.firebaseio.com",
    projectId: "axios-ex",
    storageBucket: "axios-ex.appspot.com",
    messagingSenderId: "835561925001",
    appId: "1:835561925001:web:046d92faf19f64a9011958",
    measurementId: "G-KLTB6NPMJE"
 
 })
}

export default firebase

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
index.vueは原文のままでOKだったが、データベースの反映がちょっと時間かかる 諦めないことだ
<template>
 <div class="page">
   <label>
     <span>
       お名前:
     </span>
     <input
       type="text"
       v-model="user.name"
     >
   </label>
   <label>
     <span>
       email:
     </span>
     <input
       type="text"
       v-model="user.email"
     >
   </label>
   <button
     type="button"
     @click="submit"
   >
     Submit
   </button>
 </div>
</template>

<script>
import firebase from '@/plugins/firebase'


export default {
 data () {
   return {
     user: {
       name: "",
       email: ""
     },
   }
 },
 methods: {
   submit () {
     let Ref = firebase.database().ref()
     Ref.push({ name: this.user.name, body: this.user.email })
     .then(response => {
       console.log(response, this.user)
     })
   },
 },
}
</script>
---------------------------------------------------------------------------
https://qiita.com/magaya0403/items/e292cd250184ea3fe7b0 これもすぐれもん
Vue.js + FirebaseでTodoアプリを作る ただしVueCli3
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
https://qiita.com/ririli/items/d0d3a6ae78c1b6e827fc 
Authがまともに動いたfirestoreもばっちり ただしnpm install --save firebase
のあとnpm installしないとだめなことあった なお、Bulmaをインストしてないと
うまく表示されないのが恨み store/index.jsのclearTodoは過剰コード