NIFCLOUD-mbaas / UserCommunity

ニフクラ mobile backend ユーザーコミュニティ
https://mbaas.nifcloud.com/
82 stars 18 forks source link

テーブルから取得した値を別のテーブルに保存したい #1282

Closed weather0316 closed 2 years ago

weather0316 commented 2 years ago

Monacaとニフクラでアプリ作成をしています。 1.データストアから値を取得 2.アプリに表示(HTMLに追加) 3.別のデータストアに値などを追加 という流れでをsetIntervalを使用してループする形で作成したのですが、二回目以降の3番目の流れでエラーが出てしまいます。 HTML上には表示されるのですがsetのところでエラーになっているようです。 asyncなどを使えばいいのかと思い、色々検索して試してみたのですが使い方が違うのかエラーは出続けています。 どうすればよいのか知恵をお借りしたいです。

【存在しているテーブル】 テーブル1(Ids) name, id, name_twitter

テーブル2(chat) name, contents

テーブル3(timeline) name. id. date, contents, nice, unique_key

【やりたい作業の流れ】 1.テーブル2からランダムに値を取得 2.テーブル1のreal_nameとテーブル2のnameが同じ値になるものを検索し、idとnameを取得 3.HTMLに追加 4.テーブル3に登録 5.1-4までの流れをsetIntervalを使ってループ

【エラー内容】 エラーコード:E403005 エラーメッセージ:cannot POST

【コード】


<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">
  <meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
  <script src="components/loader.js"></script>
  <script src="lib/onsenui/js/onsenui.min.js"></script>

  <link rel="stylesheet" href="components/loader.css">
  <link rel="stylesheet" href="lib/onsenui/css/onsenui.css">
  <link rel="stylesheet" href="lib/onsenui/css/onsen-css-components.css">
  <link rel="stylesheet" href="css/style.css">

</head>
<body>
  <ons-page>
    <ons-toolbar>
      <div class="center" id="toolbar-title">
      </div>
    </ons-toolbar>
    <ons-tabbar position="auto">
      <ons-tab label="TOP" page="tab1.html" active>
      </ons-tab>
      <ons-tab label="DM" page="tab2.html">
      </ons-tab>
    </ons-tabbar>
  </ons-page>

  <ons-template id="tab1.html">
    <ons-page id="first-page">
      <span id="contents"></span>
    </ons-page>
  </ons-template>

  <ons-template id="tab2.html">
    <ons-page id="second-page">
      <span id="name_list"></span>
    </ons-page>
  </ons-template>

  <script>

    const applicationKey = 'アプリケーションキー';
    const clientKey = 'クライアントキー';
    const ncmb = new NCMB(applicationKey, clientKey);

    const Task = ncmb.DataStore("chat");
    const task = new Task();
    let array = [];

    const Task_2 = ncmb.DataStore("Ids");
    const task_2 = new Task_2();

    const Dm_name = ncmb.DataStore("dm");
    const dm_name = new Dm_name();

    const Time_Line = ncmb.DataStore("timeline");
    const time_line = new Time_Line;

    let date = new Date();
    let y = date.getFullYear();
    let m = date.getMonth() + 1;
    let d = date.getDate();
    let h = date.getHours()
    let minute = date.getMinutes();
    let num = (Math.floor(Math.random()*3) + 2) * 60 * 1000;
    let num_tweet = 1;
    let ids_name = {};
    let name_real = {};
    let html;
    //エラーになった値を入れる変数群
    let err_name = [];
    let err_id = [];
    let err_contents = [];
    let err_num = 0;
    let err_dt = [];
    let err_uniqueId = [];
    //ユニークキー
    let name_twitter, id, contents, dt, unique_id;

    ons.ready(function() {
      console.log("Onsen UI is ready!");
    });

    document.addEventListener('show', function(event) {
      let page = event.target;
      let titleElement = document.querySelector('#toolbar-title');
      if (page.matches('#first-page')) {
        titleElement.innerHTML = 'TOP<img src="#" class="reload" onclick="reload()">';
      } else if (page.matches('#second-page')) {
        titleElement.innerHTML = 'DM<img src="#" class="reload" onclick="reload()">';
      }
    });

    const event = window.cordova ? 'deviceready' : 'DOMContentLoaded';

    //numミリ秒に一回処理を走らせる
    document.addEventListener(event, function() {
      html = "";
      //タイムラインが存在しているかどうかの確認
      Time_Line.fetchAll()
      .then(function(results){
        //存在していた場合
        if(results.length > 0){
          for(let i=0; i<results.length; i++){
            let tl = results[i];
            unique_id = tl["unique_key"];
            //htmlが空白であれば=で入れる
            if(html == ""){
              if(tl["nice"] == "true"){
                html = temp_nice(tl["name"], tl["id"], tl["contents"], tl["date"]);
              }else{
                html = temp(tl["name"], tl["id"], tl["contents"], tl["date"]);
              }

              document.getElementById("contents").innerHTML = html;
            }else{//空白でなければ前にくっつけていく
            if(tl["nice"] == "true"){
              html = temp_nice(tl["name"], tl["id"], tl["contents"], tl["date"]) + html;
            }else{
              html = temp(tl["name"], tl["id"], tl["contents"], tl["date"]) + html;
            }

              document.getElementById("contents").innerHTML = html;
            }
            num++;
          }
        }
      })
      .catch(function(err){
        console.log("【エラー:" + err.code + "】"  + err.message);
      });

        dm_title();
        setInterval("tweet()", num);

    });

    if (ons.platform.isIPhoneX()) {
      document.documentElement.setAttribute('onsflag-iphonex-portrait', '');
      document.documentElement.setAttribute('onsflag-iphonex-landscape', '');
    }

    //ハートのクリックイベント
    function heart(event){
      let e = event || window.event;
      let elem = e.target || e.srcElement;
      let elemId = elem.id;

      document.getElementById(elemId).classList.toggle("active_icon");
      html = document.getElementById("contents").innerHTML;

      let tf = document.getElementById(elemId).classList.contains("active_icon");

      unique_key = elemId.replace("heart_", "");

      //検索
      Time_Line.equalTo("unique_key",unique_key).fetch()
      .then(function(object){
        if(tf == true){
          object.set("nice", "true");
          return object.update();
        }else{
          object.set("nice", "false");
          return object.update();
        }
      })
      .then(function(result){
        console.log("成功!");
      })
      .catch(function(error){
        console.log("【取得or更新失敗】" + error.message);

      });

    }

    //リロード
    async function reload(){
      document.getElementById("contents").innerHTML = html;
      //err_*の配列の一つのサイズを取得
      let err_len = err_name.length;
      console.log("エラーになった数:" + err_len);
      let err_i, err_c, err_n, err_d, err_ui;
      for(let i=0; i<err_len; i++){
        //変数にi番目の値を入れる
        err_i = err_id[i];
        err_c = err_contents[i];
        err_n = err_name[i];
        err_d = err_dt[i];
        err_ui = err_uniqueId[i];
        await console.debug("【" + err_n + ", " + err_i + ", " + err_c + ", " + err_d + ", " + err_ui + "】");

        //セットする
        await time_line.set("name", err_n)
        .set("date", err_d).set("unique_key", err_ui)
        .set("contents", err_c)
        .save()
        .then(function(nemui){
          console.log("【成功】" + name_tweet + ", " + id + ", " + dt + ", " + contents);
          // 保存後の処理
          num_tweet++;
          unque_id = new Date().getTime().toString();
        })
        .catch(function(err){
          console.log("【エラー:" + err.code + "】" + err.message);
          TL(err_n, err_d, err_c, err_ui, err_i);
        });
      }
    }

    //呼び出し
    function tweet(){
      date = new Date();
      y = date.getFullYear();
      m = (date.getMonth() + 1).toString().padStart(2, '0');
      d = date.getDate().toString().padStart(2, '0');
      h = date.getHours().toString().padStart(2, '0');
      minute = date.getMinutes().toString().padStart(2, '0');
      let h_moji;
      dt = y + "-" + m + "-" + d + " " + h + ":" + minute;
      if(html == ""){
        name_twitter = "テスト";
        id = "test_plactice";
        contents = "このツイートは練習です!";
        html = temp("テスト", "test_plactice", "このツイートは練習です!", dt);
        TL(name_tweet, dt, contents, unique_id, id);
      }else{
        Task.fetchAll()
      .then(function(results){

          //ランダムに値を取得
          let rand = Math.floor(Math.random()*results.length);
          let moji = results[rand];
          unique_id = new Date().getTime().toString();
          contents = moji["contents"];
          Task_2.equalTo("name", moji["name"])
          .fetch()
          .then(function(result){
            id = result["id"];
            name_tweet = result["name_twitter"];
            h_moji = temp(name_tweet, id, contents, dt);
            console.log(name_tweet + ", " + id + ", " + contents);
            html = temp(name_tweet, id, contents, dt) + html;
          TL(name_tweet, dt, contents, unique_id, id);
      });

        document.getElementById("contents").innerHTML = html;
        num = Math.floor(Math.random()*3) + 2;
        num = num * 60 * 1000;
      });
      }

      /*
      time_line.set("name", name_tweet)
        .set("id", id)
        .set("date", dt)
        .set("unique_key", unique_id)
        .set("contents", contents)
        .save()
        .then(function(nemui){
          console.log("【成功】" + name_tweet + ", " + id + ", " + dt + ", " + contents);
          // 保存後の処理
          num_tweet++;
          unque_id = new Date().getTime().toString();
        })
        .catch(function(err){
          console.log("エラーです!");
        });
        */
    }
    function temp(name, id, contents, date){
      let moji;
      moji = "<div class='row' id = '" + unique_id + "'><span class='name'>" + name + "</span><span class='id'>" + id + "</span><span class='date_tweet'>" + date + "</span><div class='contents'>" + contents + "</div><img class='icon heart' id='heart_" + unique_id + "' src='#' onClick='heart()'><img class='icon reply' id='reply' src='#'></div>";

      return moji;

    }

    function temp_nice(name, id, contents, date){
      let moji;
      moji = "<div class='row'><span class='name'>" + name + "</span><span class='id'>" + id + "</span><span class='date_tweet'>" + date + "</span><div class='contents'>" + contents + "</div><img class='icon heart active_icon' id='heart_" + unique_id + "' src='#' onClick='heart()'><img class='icon reply' id='reply' src='#'></div>";

      return moji;

    }

    async function TL(name_tweet, dt, contents, unique_id, id){
      await time_line.set("name", name_tweet);
      await time_line.set("date", dt);
      await time_line.set("contents", contents);
      await time_line.set("id", id);
      await time_line.set("unique_key", unique_id);
            await time_line.save()
            .then(function(gameScore){
              console.log("【保存成功!】ID:" + id + ", name:" + name_tweet + ", date:" + dt + ", contents:" + contents);
              unque_id = new Date().getTime().toString();
            })
            .catch(function(err){
              console.log("【エラー:" + err.code + "】" + err.message);
              console.log("【エラーになったコンテンツ】 " + name_tweet + ", " + contents + ", " + dt);
              err_contents[err_num] = contents;
              err_dt[err_num] = dt;
              err_name[err_num] = name_tweet;
              err_id[err_num] = id;
              err_uniqueId[err_num] = unique_id;
              err_num++;
            });
    }

    function dm_title(){
      Dm_name.fetchAll()
      .then(function(name){
        for(let i=0; i<name.length; i++){
          let dm = name[i];
          document.getElementById("name_list").innerHTML += ("<div class='row_dm push-button' onclick='push_page()'>" +dm["name"]+ "</div>");
        }
      }).catch(function(err){
        console.log(":" + err.code);
      });
    }

    function registry_timeline(){

    }

  </script>
</body>
</html>
goofmint commented 2 years ago

具体的に起きているエラー、エラーの起きている部分だけを教えてください。

weather0316 commented 2 years ago

大変失礼いたしました。

【起きているエラー】 POST https://mbaas.api.nifcloud.com/2013-09-01/classes/timeline 403 (Forbidden)

【エラーの起きている部分】

async function TL(name_tweet, dt, contents, unique_id, id){
      await time_line.set("name", name_tweet);
      await time_line.set("date", dt);
      await time_line.set("contents", contents);
      await time_line.set("id", id);
      await time_line.set("unique_key", unique_id);
            await time_line.save()
            .then(function(gameScore){
              console.log("【保存成功!】ID:" + id + ", name:" + name_tweet + ", date:" + dt + ", contents:" + contents);
              unque_id = new Date().getTime().toString();
            })
            .catch(function(err){
              console.log("【エラー:" + err.code + "】" + err.message);
              console.log("【エラーになったコンテンツ】 " + name_tweet + ", " + contents + ", " + dt);
              err_contents[err_num] = contents;
              err_dt[err_num] = dt;
              err_name[err_num] = name_tweet;
              err_id[err_num] = id;
              err_uniqueId[err_num] = unique_id;
              err_num++;
            });
    }
await time_line.set("name", err_n)
        .set("date", err_d).set("unique_key", err_ui)
        .set("contents", err_c)
        .save()
        .then(function(nemui){
          console.log("【成功】" + name_tweet + ", " + id + ", " + dt + ", " + contents);
          // 保存後の処理
          num_tweet++;
          unque_id = new Date().getTime().toString();
        })
        .catch(function(err){
          console.log("【エラー:" + err.code + "】" + err.message);
          TL(err_n, err_d, err_c, err_ui, err_i);
        });

の上記二か所です

goofmint commented 2 years ago

とりあえずですが、非同期処理でない場合はawait不要です。後、awaitを使った場合はレスポンスがthenに入ってきた内容になります。

書かれている内容は次のように書き直せます。

async function TL(name_tweet, dt, contents, unique_id, id){
      time_line
        .set("name", name_tweet)
        .set("date", dt)
        .set("contents", contents)
        .set("id", id)
        .set("unique_key", unique_id);
      try {
        const gameScore = await time_line.save();
        console.log("【保存成功!】ID:" + id + ", name:" + name_tweet + ", date:" + dt + ", contents:" + contents);
        unque_id = new Date().getTime().toString();
      } catch (err) {
        console.log("【エラー:" + err.code + "】" + err.message);
        console.log("【エラーになったコンテンツ】 " + name_tweet + ", " + contents + ", " + dt);
        err_contents[err_num] = contents;
        err_dt[err_num] = dt;
        err_name[err_num] = name_tweet;
        err_id[err_num] = id;
        err_uniqueId[err_num] = unique_id;
        err_num++;
      }
    }
try {
  const nemui = await time_line
    .set("name", err_n)
    .set("date", err_d)
    .set("unique_key", err_ui)
    .set("contents", err_c)
    .save();
  console.log("【成功】" + name_tweet + ", " + id + ", " + dt + ", " + contents);
  // 保存後の処理
  num_tweet++;
  unque_id = new Date().getTime().toString();
} catch (err) {
   console.log("【エラー:" + err.code + "】" + err.message);
   TL(err_n, err_d, err_c, err_ui, err_i);
}

後はエラーの時の内容 err は403以外にもメッセージが入っていると思うので、その内容次第でしょうか。

weather0316 commented 2 years ago

またエラーが出てしまったため、console.log()の内容を少し変えてerrを表示するようにしました。 errをそのまま表示したところ以下のようになりました。 cannot POST https://mbaas.api.nifcloud.com:443/2013-09-01/classes/timeline (403)

goofmint commented 2 years ago

403しかメッセージは返っていないでしょうか?おそらくJSONの文字列が返っているかと思います。Monaca IDEであれば、そのプレビューで開発者ツールを使って通信内容が確認できるはずです。そこにエラー内容が入っているかなと。 403だけでは、ほぼ何も分かりません…。

weather0316 commented 2 years ago

大変失礼致しました。 こちらですか?

【Failed to load resource: the server responded with a status of 403 (Forbidden)】

weather0316 commented 2 years ago

constをletにし、関数の中で呼び出すことで解決しました。 ご迷惑をお掛けしました。 ありがとうございました。

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">
  <meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
  <script src="components/loader.js"></script>
  <script src="lib/onsenui/js/onsenui.min.js"></script>

  <link rel="stylesheet" href="components/loader.css">
  <link rel="stylesheet" href="lib/onsenui/css/onsenui.css">
  <link rel="stylesheet" href="lib/onsenui/css/onsen-css-components.css">
  <link rel="stylesheet" href="css/style.css">

</head>
<body>
  <ons-page>
    <ons-toolbar>
      <div class="center" id="toolbar-title">
      </div>
    </ons-toolbar>
    <ons-tabbar position="auto">
      <ons-tab label="TOP" page="tab1.html" active>
      </ons-tab>
      <ons-tab label="DM" page="tab2.html">
      </ons-tab>
    </ons-tabbar>
  </ons-page>

  <ons-template id="tab1.html">
    <ons-page id="first-page">
      <span id="contents"></span>
    </ons-page>
  </ons-template>

  <ons-template id="tab2.html">
    <ons-page id="second-page">
      <span id="name_list"></span>
    </ons-page>
  </ons-template>

  <script>

    let applicationKey = '';
    let clientKey = '';
    let ncmb = new NCMB(applicationKey, clientKey);

    let Task = ncmb.DataStore("chat");
    let task = new Task();
    let array = [];

    let Task_2 = ncmb.DataStore("Ids");
    let task_2 = new Task_2();

    let Dm_name = ncmb.DataStore("dm");
    let dm_name = new Dm_name();

    let Time_Line = ncmb.DataStore("timeline");
    let time_line = new Time_Line;

    let date = new Date();
    let y = date.getFullYear();
    let m = date.getMonth() + 1;
    let d = date.getDate();
    let h = date.getHours()
    let minute = date.getMinutes();
    let num = (Math.floor(Math.random()*3) + 2) * 60 * 1000;
    let num_tweet = 1;
    let ids_name = {};
    let name_real = {};
    let html;
    //エラーになった値を入れる変数群
    let err_name = [];
    let err_id = [];
    let err_contents = [];
    let err_num = 0;
    let err_dt = [];
    let err_uniqueId = [];
    //ユニークキー
    let name_twitter, id, contents, dt, unique_id;

    ons.ready(function() {
      console.log("Onsen UI is ready!");
    });

    document.addEventListener('show', function(event) {
      let page = event.target;
      let titleElement = document.querySelector('#toolbar-title');
      if (page.matches('#first-page')) {
        titleElement.innerHTML = 'TOP<img src="img/reload.png" class="reload" onclick="reload()">';
      } else if (page.matches('#second-page')) {
        titleElement.innerHTML = 'DM<img src="img/reload.png" class="reload" onclick="reload()">';
      }
    });

    let event = window.cordova ? 'deviceready' : 'DOMContentLoaded';

    //numミリ秒に一回処理を走らせる
    document.addEventListener(event, function() {
      html = "";
      //タイムラインが存在しているかどうかの確認
      Time_Line.fetchAll()
      .then(function(results){
        //存在していた場合
        if(results.length > 0){
          for(let i=0; i<results.length; i++){
            let tl = results[i];
            unique_id = tl["unique_key"];
            //htmlが空白であれば=で入れる
            if(html == ""){
              if(tl["nice"] == "true"){
                html = temp_nice(tl["name"], tl["id"], tl["contents"], tl["date"]);
              }else{
                html = temp(tl["name"], tl["id"], tl["contents"], tl["date"]);
              }

              document.getElementById("contents").innerHTML = html;
            }else{//空白でなければ前にくっつけていく
            if(tl["nice"] == "true"){
              html = temp_nice(tl["name"], tl["id"], tl["contents"], tl["date"]) + html;
            }else{
              html = temp(tl["name"], tl["id"], tl["contents"], tl["date"]) + html;
            }

              document.getElementById("contents").innerHTML = html;
            }
            num++;
          }
        }
      })
      .catch(function(err){
        console.log("【エラー:" + err.code + "】"  + err);
      });

        //dm_title();
        setInterval("tweet()", num);

    });

    if (ons.platform.isIPhoneX()) {
      document.documentElement.setAttribute('onsflag-iphonex-portrait', '');
      document.documentElement.setAttribute('onsflag-iphonex-landscape', '');
    }

    //ハートのクリックイベント
    function heart(event){
      let e = event || window.event;
      let elem = e.target || e.srcElement;
      let elemId = elem.id;

      document.getElementById(elemId).classList.toggle("active_icon");
      html = document.getElementById("contents").innerHTML;

      let tf = document.getElementById(elemId).classList.contains("active_icon");

      unique_key = elemId.replace("heart_", "");

      //検索
      Time_Line.equalTo("unique_key",unique_key).fetch()
      .then(function(object){
        if(tf == true){
          object.set("nice", "true");
          return object.update();
        }else{
          object.set("nice", "false");
          return object.update();
        }
      })
      .then(function(result){
        console.log("成功!");
      })
      .catch(function(error){
        console.log("【取得or更新失敗】" + error.message);
        document.getElementById(elemId).classList.toggle("active_icon");
      });

    }

    //リロード
    async function reload(){
      document.getElementById("contents").innerHTML = html;
      //err_*の配列の一つのサイズを取得
      let err_len = err_name.length;
      console.log("エラーになった数:" + err_len);
      let err_i, err_c, err_n, err_d, err_ui;
      for(let i=0; i<err_len; i++){
        //変数にi番目の値を入れる
        err_i = err_id[i];
        err_c = err_contents[i];
        err_n = err_name[i];
        err_d = err_dt[i];
        err_ui = err_uniqueId[i];
        await console.debug("【" + err_n + ", " + err_i + ", " + err_c + ", " + err_d + ", " + err_ui + "】");

        //セットする
        try {
        let nemui = await time_line
          .set("name", err_n)
          .set("date", err_d)
          .set("unique_key", err_ui)
          .set("contents", err_c)
          .save();
        console.log("【成功】" + name_tweet + ", " + id + ", " + dt + ", " + contents);
        // 保存後の処理
        num_tweet++;
        unque_id = new Date().getTime().toString();
        } catch (err) {
        console.log("【エラー:" + err.code + "】" + err);
        TL(err_n, err_d, err_c, err_ui, err_i);
        }
      }
    }

    //呼び出し
    function tweet(){
      date = new Date();
      y = date.getFullYear();
      m = (date.getMonth() + 1).toString().padStart(2, '0');
      d = date.getDate().toString().padStart(2, '0');
      h = date.getHours().toString().padStart(2, '0');
      minute = date.getMinutes().toString().padStart(2, '0');
      let h_moji;
      dt = y + "-" + m + "-" + d + " " + h + ":" + minute;
      if(html == ""){
        name_twitter = "テスト";
        id = "test_plactice";
        contents = "このツイートは練習です!";
        html = temp("テスト", "test_plactice", "このツイートは練習です!", dt);
        TL(name_tweet, dt, contents, unique_id, id);
      }else{
        Task.fetchAll()
      .then(function(results){

          //ランダムに値を取得
          let rand = Math.floor(Math.random()*results.length);
          let moji = results[rand];
          unique_id = new Date().getTime().toString();
          contents = moji["contents"];
          Task_2.equalTo("name", moji["name"])
          .fetch()
          .then(function(result){
            id = result["id"];
            name_tweet = result["name_twitter"];
            h_moji = temp(name_tweet, id, contents, dt);
            console.log(name_tweet + ", " + id + ", " + contents);
            html = temp(name_tweet, id, contents, dt) + html;

          TL(name_tweet, dt, contents, unique_id, id);
      });

        document.getElementById("contents").innerHTML = html;
        num = Math.floor(Math.random()*3) + 2;
        num = num * 60 * 1000;
        document.getElementById("contents").innerHTML = html;
      });
      reload();
      }

      /*
      time_line.set("name", name_tweet)
        .set("id", id)
        .set("date", dt)
        .set("unique_key", unique_id)
        .set("contents", contents)
        .save()
        .then(function(nemui){
          console.log("【成功】" + name_tweet + ", " + id + ", " + dt + ", " + contents);
          // 保存後の処理
          num_tweet++;
          unque_id = new Date().getTime().toString();
        })
        .catch(function(err){
          console.log("エラーです!");
        });
        */
        console.log("【HTML】" + html);
        document.getElementById("contents").innerHTML = html;
    }
    function temp(name, id, contents, date){
      let moji;
      moji = "<div class='row' id = '" + unique_id + "'><span class='name'>" + name + "</span><span class='id'>" + id + "</span><span class='date_tweet'>" + date + "</span><div class='contents'>" + contents + "</div><img class='icon heart' id='heart_" + unique_id + "' src='img/nice.png' onClick='heart()'><img class='icon reply' id='reply' src='img/reply.png'></div>";

      return moji;

    }

    function temp_nice(name, id, contents, date){
      let moji;
      moji = "<div class='row'><span class='name'>" + name + "</span><span class='id'>" + id + "</span><span class='date_tweet'>" + date + "</span><div class='contents'>" + contents + "</div><img class='icon heart active_icon' id='heart_" + unique_id + "' src='img/nice.png' onClick='heart()'><img class='icon reply' id='reply' src='img/reply.png'></div>";

      return moji;

    }

    async function TL(name_tweet, dt, contents, unique_id, id){
        Task = ncmb.DataStore("chat");
        task = new Task();
        array = [];

        Task_2 = ncmb.DataStore("Ids");
        task_2 = new Task_2();

        Dm_name = ncmb.DataStore("dm");
        dm_name = new Dm_name();

        Time_Line = ncmb.DataStore("timeline");
        time_line = new Time_Line;

      time_line
        .set("name", name_tweet)
        .set("date", dt)
        .set("contents", contents)
        .set("id", id)
        .set("unique_key", unique_id);
      try {
        let gameScore = await time_line.save();
        console.log("【保存成功!】ID:" + id + ", name:" + name_tweet + ", date:" + dt + ", contents:" + contents);
        unque_id = new Date().getTime().toString();
      } catch (err) {
        console.log("【エラー:" + err.code + "】" + err);
        console.log("【エラーになったコンテンツ】 " + name_tweet + ", " + contents + ", " + dt);
        err_contents[err_num] = contents;
        err_dt[err_num] = dt;
        err_name[err_num] = name_tweet;
        err_id[err_num] = id;
        err_uniqueId[err_num] = unique_id;
        err_num++;
      }
    }

    function registry_timeline(){

    }

  </script>
</body>
</html>